{"record":{"id":"5a5bfbe2e552f4d7","repo":"nautechsystems/nautilus_trader","slug":"verified-finalized-transaction-count-is-outside-th","errorCode":null,"errorMessage":"Verified finalized transaction count is outside the owned recovery range","messagePattern":"Verified finalized transaction count is outside the owned recovery range","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":4041,"sourceCode":"            anyhow::ensure!(\n                bootstrap.migration.is_none(),\n                \"Verification migration was supplied for an initialized signer\"\n            );\n            anyhow::ensure!(\n                manifest_version == bootstrap.manifest_version\n                    && manifest_digest == bootstrap.manifest_digest,\n                \"Execution verification manifest identity changed\"\n            );\n            anyhow::ensure!(\n                stored_nonce == next_canonical_nonce,\n                \"Canonical nonce ledger changed during verification bootstrap\"\n            );\n\n            if observed_canonical_nonce != stored_nonce {\n                let expected_observed_nonce = stored_nonce\n                    .checked_add(1)\n                    .ok_or_else(|| anyhow::anyhow!(\"Canonical nonce overflow\"))?;\n                anyhow::ensure!(\n                    observed_canonical_nonce == expected_observed_nonce,\n                    \"Verified finalized transaction count is outside the owned recovery range\"\n                );\n                let recovery = sqlx::query_as::<_, (Option<i64>, String, i64)>(\n                    \"\n                    SELECT\n                        intent.nonce,\n                        intent.status,\n                        COUNT(hash.id) FILTER (\n                            WHERE hash.current\n                              AND hash.payload_expected\n                              AND ((hash.raw_transaction IS NOT NULL)::INTEGER\n                                   + (hash.sealed_transaction IS NOT NULL)::INTEGER) = 1\n                              AND hash.status IN (\n                                  'broadcast', 'included', 'replaced', 'dropped', 'reorged'\n                              )\n                        )\n                    FROM execution_intent AS intent","sourceCodeStart":4023,"sourceCodeEnd":4059,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L4023-L4059","documentation":"During bootstrap of an initialized signer, the observed canonical nonce (verified finalized transaction count) must equal either the stored ledger nonce or exactly stored_nonce + 1 (crates/adapters/blockchain/src/cache/database.rs:4041). Any other relationship — advanced by more than one, or the observed count being behind the ledger — means the durable canonical nonce and the verified finalized count have diverged beyond the single sanctioned recovery step, so bootstrap aborts.","triggerScenarios":"Observed canonical nonce differs from the stored next_canonical_nonce by more than +1, or is smaller than the stored value — e.g. transactions finalized outside the tracked ledger, a restored database under a wallet that kept transacting, or an incorrect observed count computed from a partial verification scan.","commonSituations":"Restoring an old database snapshot while the wallet continued trading on-chain; multiple writers sending transactions for the same wallet outside this system; reorg/finality miscount making the observed count jump or lag; pointing the bootstrap at the wrong chain_id so counts don't line up.","solutions":["Compare stored next_canonical_nonce vs observed_canonical_nonce to see the direction and size of divergence.","If the ledger is behind, ensure exactly one in-flight owned intent at the durable nonce exists (the code requires one recoverable retained payload) and re-run bootstrap; this error itself means the recovery-range guard failed, so fix the divergence first.","Reconcile against the chain: rebuild the ledger from the wallet's actual finalized nonce instead of trusting either divergent value.","Check for out-of-band transactions from the same wallet (other bots, manual sends) and eliminate them.","Verify the correct chain_id/wallet pairing is being bootstrapped."],"exampleFix":"// before\n// observed nonce jumped by 3 due to out-of-band sends from the same wallet\nbootstrap(chain_id, wallet, next_canonical_nonce, observed = stored + 3)?;\n\n// after\n// stop out-of-band senders, reconcile ledger with on-chain finalized nonce, then bootstrap with the reconciled count\nlet reconciled = db.reconcile_canonical_nonce_from_chain(chain_id, wallet).await?;\nbootstrap(chain_id, wallet, reconciled.next_canonical_nonce, reconciled.observed).await?;","handlingStrategy":"validation","validationCode":"let observed = count_verified_finalized(chain_id, wallet)?;\nlet stored = fetch_stored_nonce(chain_id, wallet)?;\nif observed != stored && observed != stored.checked_add(1).ok_or(anyhow::anyhow!(\"overflow\"))? {\n    return Err(anyhow::anyhow!(\"observed nonce {observed} diverges from ledger {stored}; reconcile before bootstrap\"));\n}","typeGuard":null,"tryCatchPattern":"match bootstrap_verification(...).await {\n    Err(e) if e.to_string().contains(\"outside the owned recovery range\") => {\n        // reconcile canonical nonce from on-chain finalized transactions, then retry bootstrap\n    }\n    other => other?,\n}","preventionTips":["Never send transactions for a verification-managed wallet outside this system","Reconcile the durable ledger against on-chain finalized nonces before restarts or restores","When restoring database snapshots, quiesce the wallet first so the ledger and chain cannot diverge","Double-check chain_id and wallet pairing when configuring the verification bootstrap"],"tags":["blockchain","database","consistency","nonce"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}