Environment
-
Bisq version: upgraded to v1.10.3 (the post-hack hardening release); later showed v1.10.4 during troubleshooting
-
OS: Windows (32 GB RAM)
-
Network: Bitcoin mainnet over Tor
-
Data directory age: ~8 months (created Nov 2024), ~3 GB total,
btc_mainnet~2.77 GB — normal size -
Wallet: encrypted (AES-256-CBC / Scrypt)
Summary
After upgrading to the v1.10.x hardening line, my wallet ended up with a corrupted UTXO set: the displayed available balance became overstated, and any new transaction the wallet tried to build (a trade deposit tx, and later trades) failed to broadcast — it never appeared in the mempool on public explorers, even after hours and multiple restarts. The corruption appears to have been caused/worsened by SPV resyncs that were repeatedly interrupted by Java heap space (OutOfMemory) crashes. Notably, the overstated balance grew larger after each additional crashed resync (from ~0.185 BTC to ~0.6 BTC), which strongly suggests the resync process was leaving the UTXO set in a progressively more inconsistent state rather than repairing it.
I was ultimately able to recover all real funds by using Funds → Send with “custom inputs,” selecting only the addresses I had independently verified as unspent on-chain, and sweeping them to an external wallet — that transaction broadcast and confirmed normally. This points fairly clearly at the wallet’s internal UTXO tracking being out of sync with the actual chain, rather than any on-chain problem.
Timeline / what happened
-
Upgraded to v1.10.3 (released after the exploit).
-
Started getting “deposit transaction (2-of-2 multisig) is absent” errors on trades; trades were failing with the “move to failed trades” prompt.
-
Attempted an SPV resync to fix it — the resync crashed midway with
Java heap space(OutOfMemory). Restarted the app; the resync eventually “completed” after a restart, but the problem persisted. Repeated this more than once. -
Trade
430935(BTC seller) got stuck at “Aguardar confirmação da blockchain.” Its deposit txid showed “Transação não encontrada / Aguardando que apareça no mempool” — both inside Bisq and on mempool.space. The tx had apparently been signed locally but never broadcast to the network. -
Noticed the available balance was overstated: after a day where I had sold ~0.07–0.08 BTC in completed trades, the balance had not decreased accordingly (
BTC_AVAILABLEstill ~0.185 BTC). -
Hit repeated
Java heap spacecrashes, plus a JavaFX NPE:Cannot invoke "javafx.scene.Scene.isDepthBuffer()" because the return value of "javafx.scene.Node.getScene()" is null, when navigating (e.g. toward DAO Network Monitor). -
Got a “Your Bisq DAO state needs to be resynced” prompt. The peer-based DAO resync got stuck for ~50 minutes on a single block (e.g. 958,877 of 958,892) and never finished. “Rebuild DAO state from resources” did complete successfully and was much faster.
-
After yet another crash-riddled resync, the overstated balance grew to ~0.6 BTC — clearly divergent from reality.
Diagnostic evidence
Ctrl+J (Show Wallet Data) balances block — the overstated figure was present at the wallet-engine level, not just the UI summary:
Balances:
0.18536948 BTC AVAILABLE
0.18536948 BTC AVAILABLE_SPENDABLE
Transactions:
2 pending
7 unspent
2088 spent
-
The
2 pendingwere the stuck deposit + fee txs for trade430935(they reference inputs the network rejects, so they sit unconfirmed forever). -
The
7 unspentoutputs did not match on-chain reality — some outputs the wallet believed were unspent had already been spent by earlier (completed) trade payouts.
Deposit txid for the stuck trade (430935): 3d174c64bd30f5edd193f8682ecb60ab5eadaf4fdd3cdce028a5dcaac64d7315 — not found in mempool on public explorers.
Interpretation: the wallet was trying to build new transactions using phantom/already-spent UTXOs as inputs. Any honest node rejects such a tx (it references an output that no longer exists), so it never propagates — which is exactly the “signed but never appears in mempool” symptom, and also explains the inflated balance (spent outputs still counted as spendable).
What fixed it (recovery)
-
Went to Funds → Send funds, switched input selection to “Usar inputs personalizados” (custom inputs).
-
Independently verified each address’s balance on a block explorer, and selected only the addresses that were genuinely unspent on-chain.
-
Set the destination to an external (hardware) wallet address and broadcast.
-
The sweep transaction broadcast and confirmed normally. All real funds recovered.
This confirms the funds were always safe on-chain; the problem was purely Bisq’s local UTXO accounting.
Open questions / requests
-
Is the v1.10.x hardening (stricter deposit/payout/DAO validation) interacting badly with interrupted SPV resyncs to corrupt the local UTXO set? The fact that the overstated balance grew with each crashed resync seems like an important clue.
-
Could Bisq guard against
Java heap spacecrashes during resync (and/or make resync resumable/atomic) so a mid-resync OOM doesn’t leave the wallet in a worse state than before? -
For the stuck open trade: since no deposit was ever locked on-chain, mediation/arbitration is (correctly) unavailable, and the in-app dialog says no trade funds/deposit were locked (only possibly some miner/trade fees lost). Is the fee-reimbursement process (Failed_Trades_-_Reimbursement_of_Trade_Fees_and_Miner_Fees) the correct path here?
-
Is anyone else seeing “deposit transaction absent” + inflated balance + deposit tx failing to broadcast specifically after upgrading into the v1.10.x releases?
Notes for others hitting this
-
Don’t stack SPV resyncs, and don’t force-kill Bisq mid-resync — that appears to be what corrupts the UTXO set.
-
If your balance looks wrong or a tx won’t broadcast, verify individual addresses/outputs on a block explorer before trusting Bisq’s displayed balance.
-
The custom-inputs sweep (selecting only explorer-verified unspent addresses) is a clean way to recover funds to an external wallet without relying on the corrupted UTXO set. If even that fails to broadcast, the next fallback is restoring the seed (+ wallet date) into a fresh Bisq data directory or into Electrum, which rebuilds the UTXO set from the chain.
-
Your coins live on-chain, not in Bisq’s cache — a corrupted local wallet is recoverable as long as you have your seed words + wallet date.