You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
full_scan over RPC ignores --scan-stop-gap: restored wallet silently misses funds at external index >= 25 #340
Environment: bdk-cli 4.0.0 from crates.io (tag v4.0.0, git 5b3cb00, built with --features rpc), bdk_wallet 3.2.0, bdk_chain 0.23.3, bdk_bitcoind_rpc 0.22.0, Bitcoin Core v31.1.0, regtest, macOS arm64
What happens
Restoring a wpkh() descriptor exported from Bitcoin Core and running full_scan with --client-type rpc does not find funds received at external index 25 or higher when no lower index has been used. The command exits with status 0, prints "Full scan completed successfully." and reports a zero balance. Passing --scan-stop-gap 100 does not change the result, even though full_scan --help documents that flag without noting that it has no effect with --client-type rpc.
Funded external index (only)
Core getbalance
bdk-cli balance
24
1.00000000
100000000 sat
25
1.00000000
0
30
1.00000000
0
30 with --scan-stop-gap 100
1.00000000
0
bdk-cli's own event output shows the chain was fully walked in every case ("Chain tip advanced from height 0 to …"), but a "Transaction … confirmed" event appears only for index 24.
Expected behavior
Either the funds are found when --scan-stop-gap is raised (as the help text suggests), or the CLI warns that the flag has no effect with --client-type rpc.
Why (from reading the v4.0.0 source)
In src/handlers/online.rs, stop_gap is passed to the Electrum (L123) and Esplora (L134) clients, but the RPC branch (L141+) walks blocks with Emitter and never reads it. Detection then depends on the keychain lookahead (DEFAULT_LOOKAHEAD = 25 in bdk_chain 0.23.3). bdk_wallet already exposes a lookahead() parameter for this, but bdk-cli does not use or expose it.
Related library-level context: bitcoindevkit/bdk_wallet#83, where it was noted that lookahead and stop_gap "should be fixed together". This report is about the CLI surface: the flag is accepted but has no effect with RPC, and there is no way to raise the lookahead from the CLI.
Why it matters
Bitcoin Core wallets pre-derive 1000 keys by default (DEFAULT_KEYPOOL_SIZE), so funds past index 24 are plausible. A user restoring such a backup with bdk-cli over RPC sees a successful scan and a zero balance.
Possible fixes (maintainers' call)
Pass --scan-stop-gap through as the wallet lookahead for block-based backends, or add a --lookahead option.
Warn or error when --scan-stop-gap is passed with --client-type rpc.
Follow-up: same wallets scanned through the Esplora backend (Blockstream electrs new-index, commit cb7c72f, regtest; bdk-cli 4.0.0 rebuilt with --features rpc,esplora, bdk_esplora 0.22.2).
Funded external index (only)
Core
bdk-cli RPC
bdk-cli Esplora (default)
bdk-cli Esplora --scan-stop-gap 40
19
found
found
found
found
20
found
found
0
found
24
found
found
0
found
25
found
0
0
found
30
found
0
0
found
With Esplora, --scan-stop-gap works as documented: raising it recovers every case. This confirms the issue is specific to the RPC branch.
With default settings, the same descriptor yields different balances depending on the backend (RPC sees up to index 24 via the lookahead of 25; Esplora sees up to index 19 via the stop gap of 20). I'm not reporting that as a bug; noting it because a user switching backends would see funds appear or disappear.
I reproduced this locally to check whether it still affects current master.
Setup
My setup are as follow: regtest, Bitcoin Core v32.1.0, Blockstream Esplora electrs a33e97e1. I tested bdk-cli v4.0.0 (5b3cb00) and current master (6579837), both built with --features rpc,esplora. Each row is a fresh wpkh wallet with 1 BTC sent to only that external index. Core sees the funds in every case, and every scan exits 0.
Funded index
RPC
RPC --scan-stop-gap 100
Esplora (default)
Esplora --scan-stop-gap 40
19
found
found
found
found
20
found
found
0
found
24
found
found
0
found
25
0
0
0
found
30
0
0
0
found
v4.0.0 and master behave the same, so this is still present on master.
I also tried loading the wallet with .lookahead(100) in src/persister.rs (a scratch patch, not a PR). With that, RPC finds funds at index 25, 30 and 99, and misses index 100. So on RPC the lookahead alone decides what gets found, and the limit is exactly lookahead - 1.
One constraint for the fix: the wallet is loaded in persister.rs before full_scan runs, so a full_scan flag can't change the lookahead unless it's passed into wallet loading.
Possible direction: a wallet-level --lookahead option passed to Wallet::load() / create(), plus a runtime warning when --scan-stop-gap is used with an RPC wallet.
If this approach sounds right, I am happy to work on the lookahead part. @emma31-dev, I don't want to overlap with #367 , so let me know if you were planning to cover it.
@Olorunshogo my PR mostly fixes gating the flags to the appropriate client It's best I just add this so it completely closes the issue rather than to open a separate fix or if you have time you send a PR to my branch adding this
Activity
devdavidejesus commentedon Sep 28, 2026
Follow-up: same wallets scanned through the Esplora backend (Blockstream electrs
new-index, commit cb7c72f, regtest; bdk-cli 4.0.0 rebuilt with--features rpc,esplora, bdk_esplora 0.22.2).--scan-stop-gap 40--scan-stop-gapworks as documented: raising it recovers every case. This confirms the issue is specific to the RPC branch.Script and log added to the same gist (labels in Portuguese): https://gist.github.com/devdavidejesus/25b34cb7d2735f04791800c12b21d59d
Olorunshogo commentedon Nov 6, 2026
I reproduced this locally to check whether it still affects current master.
Setup
My setup are as follow: regtest, Bitcoin Core v32.1.0, Blockstream Esplora electrs
a33e97e1. I tested bdk-cli v4.0.0 (5b3cb00) and current master (6579837), both built with--features rpc,esplora. Each row is a freshwpkhwallet with 1 BTC sent to only that external index. Core sees the funds in every case, and every scan exits 0.--scan-stop-gap 100--scan-stop-gap 40v4.0.0 and master behave the same, so this is still present on master.
I also tried loading the wallet with
.lookahead(100)insrc/persister.rs(a scratch patch, not a PR). With that, RPC finds funds at index 25, 30 and 99, and misses index 100. So on RPC the lookahead alone decides what gets found, and the limit is exactlylookahead - 1.One constraint for the fix: the wallet is loaded in
persister.rsbeforefull_scanruns, so afull_scanflag can't change the lookahead unless it's passed into wallet loading.Possible direction: a wallet-level
--lookaheadoption passed toWallet::load()/create(), plus a runtime warning when--scan-stop-gapis used with an RPC wallet.If this approach sounds right, I am happy to work on the lookahead part. @emma31-dev, I don't want to overlap with #367 , so let me know if you were planning to cover it.
emma31-dev commentedon Nov 6, 2026
@Olorunshogo my PR mostly fixes gating the flags to the appropriate client It's best I just add this so it completely closes the issue rather than to open a separate fix or if you have time you send a PR to my branch adding this
emma31-dev commentedon Nov 6, 2026
@Olorunshogo don't bother i'll fix it
Olorunshogo commentedon Nov 6, 2026
This sounds good too. Thanks.
These are a couple of things from my testing that might help @emma31-dev:
src/persister.rs, sincefull_scanruns after that.rpc, esplorabuild,--scan-stop-gapis still accepted for an RPC wallet, so a runtime check on the client type would cover that case.Happy to test it once it's pushed. I have a regtest setup that funds a single index (19, 20, 24, 25, 30, 99, 100) and scan it over RPC and Esplora.
emma31-dev commentedon Nov 6, 2026
@Olorunshogo I wouldn't like to work on the lookahead until @tvpeter approves it. I have made some changes feel free to review
fix(full_scan): gate --scan-stop-gap to backends that use it