$ bitcoin-cli -rpcwallet=mywallet gettransaction 3f1c...e9a2
{
"confirmations": 0,
"bip125-replaceable": "yes",
...
}
Hours later it still has zero confirmations. Nothing is broken. Miners fill blocks with the highest-feerate transactions they know about, and yours sits below the cutoff. You have two ways to raise its effective feerate: Replace-By-Fee (RBF), where the sender re-signs the transaction with a higher fee, and Child-Pays-For-Parent (CPFP), where anyone with an output of the transaction spends it with a high fee.
Why transactions get stuck
Block space is sold by virtual byte, not by amount. A transaction paying 2 sat/vB waits behind everything paying more. If fee pressure rises after you broadcast, the fee estimate that looked fine can end up far below the going rate.
Several things can happen next:
- Demand drops and it confirms on its own.
- Nodes whose mempools are full evict it for falling below their dynamic minimum feerate.
- It expires. Bitcoin Core drops mempool transactions after two weeks by default (
-mempoolexpiry).
Being evicted doesn't cancel anything. The signed transaction is still valid and can be rebroadcast by anyone who has it. Your wallet should treat it as pending until it confirms or something conflicting confirms.
Check where you stand:
bitcoin-cli getmempoolentry <txid> # errors if your node no longer has it
bitcoin-cli estimatesmartfee 3 # current estimate for ~3 blocks, in BTC/kvB
Replace-By-Fee (RBF)
RBF means broadcasting a new version of the transaction that spends at least one of the same inputs and pays a higher fee. Nodes swap it in for the original, and only one of the two can ever confirm.
Bitcoin Core's replacement policy (which grew out of BIP-125) requires, roughly, that the replacement:
- pays a higher feerate than the transaction(s) it replaces,
- pays a higher absolute fee than the originals combined, plus enough to cover relaying its own size at the incremental relay feerate,
- doesn't evict too many descendant transactions.
Originally, a transaction had to opt in by setting an input's nSequence below 0xfffffffe. Since Bitcoin Core 28.0, nodes accept replacements whether or not the original signalled ("full RBF") by default. Some wallets still refuse to bump a transaction that didn't signal, so enable RBF in your wallet anyway.
If you sent from a Bitcoin Core wallet:
# Bump to 25 sat/vB; the wallet reduces your change output to pay for it
bitcoin-cli -rpcwallet=mywallet -named bumpfee <txid> fee_rate=25
# Watch-only / hardware wallet: get an unsigned PSBT instead
bitcoin-cli -rpcwallet=mywallet -named psbtbumpfee <txid> fee_rate=25
bumpfee returns a new txid. Anything that tracks the old txid (your database, a block explorer link you sent someone) must switch to the new one. The old one will never confirm.
RBF can also redirect the payment. That is exactly why a merchant should never treat an unconfirmed payment as settled.
Child-Pays-For-Parent (CPFP)
If you can't replace the transaction (you're the receiver, or the sender's wallet doesn't support RBF), spend one of its outputs in a new transaction with a high fee. Miners select transactions by ancestor feerate: a child can only be mined together with its unconfirmed parent, so they evaluate the pair as a package:
package feerate = (parent fee + child fee) / (parent vsize + child vsize)
Say the parent is 200 vB and pays 2 sat/vB (400 sats), and you want the package at 20 sat/vB with a 150 vB child:
needed total fee = 20 × (200 + 150) = 7,000 sats
child fee = 7,000 − 400 = 6,600 sats (44 sat/vB on its own)
With Bitcoin Core, spend the specific output back to yourself:
bitcoin-cli -rpcwallet=mywallet -named sendall \
recipients='["bc1q...your-own-address"]' \
fee_rate=20 \
options='{"inputs":[{"txid":"<parent_txid>","vout":1}]}'
Recent Bitcoin Core wallets account for low-feerate unconfirmed ancestors when you set fee_rate, so the child should come out large enough to bring the package up to about 20 sat/vB. Always verify rather than assume:
bitcoin-cli getmempoolentry <child_txid>
# compare fees.ancestor / ancestorsize against your target feerate
CPFP limits to know:
- The parent must still be in the mempools miners see. If nodes have already evicted it for low fees, a child alone can't pull it back in. Newer Bitcoin Core versions relay a one-parent-one-child package together, but don't count on every node doing so.
- You need an output you control. A sender can use their change output, and a receiver can use their payment output.
- A child adds bytes, so for the same result CPFP usually costs more than RBF.
RBF vs CPFP
| RBF | CPFP | |
|---|---|---|
| Who can do it | Sender (holds the input keys) | Anyone with an output of the tx |
| Txid | Changes | Parent txid unchanged |
| Extra block space | None | Adds a child transaction |
| Works if parent was evicted | Yes (it's a fresh broadcast) | Only with package relay |
| Can change recipients | Yes | No |
If it's gone from the mempool
An evicted transaction can still confirm if someone rebroadcasts it, so "gone" isn't "cancelled". The only real cancellation is a conflicting transaction that spends the same input at a proper fee and confirms. RBF is exactly that, and it works even after eviction because it's a fresh broadcast. In Bitcoin Core you can also free the inputs with abandontransaction <txid>, which only works once the transaction is out of your node's mempool, and then spend them again. Until the conflicting transaction confirms, the original can still win.
Fixes
- Check the feerate you paid against
estimatesmartfeeand against what recent blocks included. - As the sender:
bumpfee(orpsbtbumpfee), then track the new txid. - As the receiver, or when RBF isn't available: CPFP from an output you control, and size the child for the package feerate.
- Confirm the result with
getmempoolentry(ancestor fee and size). - Build wallets that signal RBF, use current fee estimates, and never treat zero-confirmation payments as final.
Get the weekly commit
New blockchain deep dives every week.