Possible race condition with broadcasting transaction while sending on restart #35589

issue VojtechMyslivec opened this issue on June 23, 2026
  1. VojtechMyslivec commented at 12:05 PM on June 23, 2026: none

    Is there an existing issue for this?

    • I have searched the existing issues

    Current behaviour

    There was a RPC send call shortly after Bitcoin Core restart. Everything work as it should. RPC response, gettransaction shows outgoing amount with 0 confirmation, log messages, ... However, the transaction wasn't broadcasted. So Bitcoin Core wallet shows sent TX but no other node, especially the receiver's one didn't know about the transaction.

    Later bitcoin core restart (after ~22 hours) didn't help. I needed to list transactions, get the raw hex and broadcast it manually.

    Expected behaviour

    Transaction is broadcasted on restart or after mempool load from disk

    Steps to reproduce

    • restart bitcoind
    • send transaction through RPC call
    • look for the transaction on bitcoin explorer enywhere else

    Relevant log output

    --- Restart initiated ---
    ...
    2026-06-22T12:56:00Z Verifying last 6 blocks at level 3
    2026-06-22T12:56:00Z Verification progress: 0%
    ...
    2026-06-22T12:56:03Z Verification progress: 99%
    2026-06-22T12:56:03Z Verification: No coin database inconsistencies in last 6 blocks (31335 transactions)
    2026-06-22T12:56:03Z Block index and chainstate loaded
    2026-06-22T12:56:03Z Using SQLite Version 3.46.1
    2026-06-22T12:56:03Z Using wallet /var/lib/bitcoind/production
    2026-06-22T12:56:03Z init message: Loading wallet…
    2026-06-22T12:56:03Z [production] Last client version = 300200
    2026-06-22T12:56:38Z [production] Descriptors: 24, Descriptor Keys: 0 plaintext, 1 encrypted, 1 total.
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = legacy, internal = false
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = p2sh-segwit, internal = false
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = bech32, internal = false
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = bech32m, internal = false
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = legacy, internal = true
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = p2sh-segwit, internal = true
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = bech32, internal = true
    2026-06-22T12:56:39Z [production] Setting spkMan to active: id = ..., type = bech32m, internal = true
    2026-06-22T12:57:36Z [production] Wallet completed loading in           92324ms
    2026-06-22T12:57:36Z [production] setKeyPool.size() = 8000
    2026-06-22T12:57:36Z [production] mapWallet.size() = 288043
    2026-06-22T12:57:36Z [production] m_address_book.size() = 15800
    2026-06-22T12:57:36Z Setting NODE_NETWORK on non-prune mode
    2026-06-22T12:57:36Z block tree size = 954914
    2026-06-22T12:57:36Z nBestHeight = 954842
    2026-06-22T12:57:36Z initload thread start
    2026-06-22T12:57:36Z Loading 105921 mempool transactions from file...
    2026-06-22T12:57:36Z Loaded 2 addresses from "anchors.dat"
    2026-06-22T12:57:36Z 2 block-relay-only anchors will be tried for connections.
    2026-06-22T12:57:36Z init message: Starting network threads…
    2026-06-22T12:57:36Z net thread start
    2026-06-22T12:57:36Z dnsseed thread start
    2026-06-22T12:57:36Z Waiting 300 seconds before querying DNS seeds.
    2026-06-22T12:57:36Z addcon thread start
    2026-06-22T12:57:36Z opencon thread start
    2026-06-22T12:57:36Z init message: Done loading
    2026-06-22T12:57:36Z msghand thread start
    2026-06-22T12:57:36Z Leaving InitialBlockDownload (latching to false)
    2026-06-22T12:57:36Z [production] Submitting wtx 84...71 to mempool for relay
    2026-06-22T12:57:36Z [production] Submitting wtx 77...28 to mempool for relay
    2026-06-22T12:57:36Z [production] ResubmitWalletTransactions: resubmit 1 unconfirmed transactions
    2026-06-22T12:57:36Z [production] AddToWallet 77...28   InMempool
    2026-06-22T12:57:36Z [production] AddToWallet 77...28   InMempool
    2026-06-22T12:57:36Z New block-relay-only v2 peer connected: version: 70016, blocks=954843, peer=0
    2026-06-22T12:57:36Z Saw new header hash=0000000000000000000135bd7dcd740e8f7b1113044db347649e8f60d2a93f9c height=954843 peer=0
    2026-06-22T12:57:39Z New outbound-full-relay v1 peer connected: version: 70016, blocks=954843, peer=3
    2026-06-22T12:58:02Z New outbound-full-relay v1 peer connected: version: 70016, blocks=954843, peer=7
    2026-06-22T12:58:33Z New outbound-full-relay v1 peer connected: version: 70015, blocks=954843, peer=10
    2026-06-22T12:58:45Z UpdateTip: new best=0000000000000000000135bd7dcd740e8f7b1113044db347649e8f60d2a93f9c height=954843 version=0x2000e000 log2_work=96.256767 tx=1382125259 date='2026-06-22T12:57:10Z' progress=1
    .000000 cache=3.3MiB(23642txo)
    2026-06-22T12:58:46Z [production] Coin Selection: Algorithm:knapsack, Waste Metric Score:-204
    2026-06-22T12:58:46Z [production] Fee Calculation: Fee:286 Bytes:143 Tgt:0 (requested 0) Reason:"PayTxFee set" Decay 0.00000: Estimation: (-1 - -1) 0.00% 0.0/(0.0 0 mem 0.0 out) Fail: (-1 - -1) 0.00% 0.0/(0.0 0 
    mem 0.0 out)
    2026-06-22T12:58:47Z [production] Coin Selection: Algorithm:knapsack, Waste Metric Score:-204
    2026-06-22T12:58:47Z [production] Fee Calculation: Fee:286 Bytes:143 Tgt:0 (requested 0) Reason:"PayTxFee set" Decay 0.00000: Estimation: (-1 - -1) 0.00% 0.0/(0.0 0 mem 0.0 out) Fail: (-1 - -1) 0.00% 0.0/(0.0 0 
    mem 0.0 out)
    2026-06-22T12:58:47Z [production] Fee non-grouped = 286, grouped = 286, using grouped
    
    --- send RPC call initiated now ---
    2026-06-22T12:58:47Z [production] CommitTransaction:
    CTransaction(hash=d9...41, ver=2, vin.size=1, vout.size=2, nLockTime=954843)
        CTxIn(COutPoint(48...5d, 1), scriptSig=, nSequence=42...93)
        CScriptWitness(2a...86)
        CTxOut(nValue=0.00715016, scriptPubKey=00...09)
        CTxOut(nValue=0.01284487, scriptPubKey=51...ee)
    
    2026-06-22T12:58:47Z [production] AddToWallet d9...4c  newupdate Inactive (abandoned=0)
    2026-06-22T12:58:47Z [production] Submitting wtx d9...4c to mempool for relay
    2026-06-22T12:58:47Z [production] AddToWallet d9...4c   InMempool
    --- it never gets broadcasted --- 
    
    2026-06-22T12:58:56Z New outbound-full-relay v2 peer connected: version: 70016, blocks=954843, peer=11
    2026-06-22T12:59:04Z P2P peers available. Skipped DNS seeding.
    2026-06-22T12:59:04Z dnsseed thread exit
    ...
    2026-06-22T13:00:31Z New outbound-full-relay v2 peer connected: version: 70016, blocks=954843, peer=15
    2026-06-22T13:00:39Z Progress loading mempool transactions from file: 10% (tried 10593, 95328 remaining)
    ...
    2026-06-22T13:03:19Z New block-relay-only v2 peer connected: version: 70016, blocks=954843, peer=28
    2026-06-22T13:03:49Z Progress loading mempool transactions from file: 20% (tried 21185, 84736 remaining)
    2026-06-22T13:03:52Z Progress loading mempool transactions from file: 30% (tried 31777, 74144 remaining)
    ...
    2026-06-22T13:04:05Z Progress loading mempool transactions from file: 80% (tried 84737, 21184 remaining)
    2026-06-22T13:04:08Z Progress loading mempool transactions from file: 90% (tried 95329, 10592 remaining)
    2026-06-22T13:04:11Z Imported mempool transactions from file: 102043 succeeded, 2369 failed, 2 expired, 1507 already there, 0 waiting for initial broadcast
    2026-06-22T13:04:11Z initload thread exit
    ...
    

    bitcoin-cli gettransaction d9...4c show this information but the transaction was not visible on any bitcoin explorer out there:

    {
      "amount": -0.007***,
      "fee": -0.000002***,
      "confirmations": 0,
      "trusted": true,
      "txid": "d9...4c",
      "wtxid": "61...7e",
      "walletconflicts": [
      ],
      "mempoolconflicts": [
      ],
      "time": 1782133127,
      "timereceived": 1782133127,
      "bip125-replaceable": "yes",
      "comment": "***;",
      "details": [
        {
          "address": "bc1q0***h",
          "category": "send",
          "amount": -0.007***,
          "vout": 0,
          "fee": -0.000002***,
          "abandoned": false
        }
      ],
      "hex": "02000000000101...db910e00",
      "lastprocessedblock": {
        "hash": "000000000000000000001d4ef0ad83d69d00f3d49c8e9ce9cfef52266af61b2f",
        "height": 954993
      }
    }
    

    How did you obtain Bitcoin Core

    Pre-built binaries

    What version of Bitcoin Core are you using?

    v30.2

    Operating system and version

    Debian GNU/Linux 11

    Machine specifications

    AWS ec2 instance with Debian OS and gp3 disk. Bitcoin Core installed from bulit binaries on github

  2. maflcko commented at 10:16 AM on June 25, 2026: member

    ResubmitWalletTransactions is called before the first peer is added, so the outcome is expected. Not sure what the best fix here would be.

  3. maflcko added the label Wallet on Jun 25, 2026
  4. maflcko added the label P2P on Jun 25, 2026
  5. mzumsande commented at 11:57 PM on June 25, 2026: contributor

    ResubmitWalletTransactions is called before the first peer is added, so the outcome is expected. Not sure what the best fix here would be.

    but that would concern tx 77...28 which seems unrelated. Also, it is called during init in https://github.com/bitcoin/bitcoin/blob/93012d7ff918eef41adf453bf10ddb4da21f3df4/src/wallet/wallet.cpp#L3335 with MEMPOOL_NO_BROADCAST, so it wouldn't broadcast to peers anyway, by design.

    The way I read the report the tx in question is d9...4c which got added to the mempool when there were already at least 3 peers 3,5,7. Even if these disconnected immediately after connecting (not shown in the log) and there were no peers at the time, as a newly submitted tx it should have been added to the unbroadcast set and re-broadcast every 10-15 minutes until at least one peer fetches it.

    So maybe this was a case of bad peers (that did fetch the tx, removing it from the unbroadcast set, but didn't relay it to their peers for some reason)?

    After that, rebroadcast of txns that were once requested by a peer (so are no longer in the unbroadcast set) should happen on a 12-24h timer: https://github.com/bitcoin/bitcoin/blob/93012d7ff918eef41adf453bf10ddb4da21f3df4/src/wallet/wallet.cpp#L2097. Probably it was an unfortunate decision to restart after 22h instead of waiting for 2 more hours, because the restart reset the timer to another 12-24h instead of triggering an immediate rebroadcast event.

  6. maflcko commented at 8:19 AM on June 26, 2026: member

    Ok, I see. There are several bugs reported here and I only saw one: "Expected behaviour: Transaction is broadcasted on restart"

    The bugs I see are:

    1. logging bug: The debug log says Resubmit ... to mempool for relay, which is wrong, because it has NO_BROADCAST set. The debug log was already fixed in commit 07a926474b5a6fa1d3d4656362a0117611f6da2f in the v31 release.
    2. A UX bug: The initial send of the tx didn't seem to make it to the peers/network. It seems unlikely, since there were three peers, and the tx had a fee rate of 2sat/Byte, which should have been enough at that time. The exact debug logs on p2p traffic and unbroadcast set removal are missing here, so this remains the most plausible explanation. In times of different "fee weather", a failed broadcast may happen more often.
    3. A UX bug: The forced rebroadcast after 12h-24h did not trigger. There are no logs, bug likely because the node was shut down too early. This may be more likely to hit for users that only leave their node running for a few hours every day.

    Point 1. is already fixed, and I don't think anything can be done about 2.

    For 3., I think someone would have to pick up #21061 again?


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-07-02 03:50 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me