{"record":{"id":"c5ead93a92556658","repo":"nautechsystems/nautilus_trader","slug":"canonical-nonce-advanced-without-an-authenticated-c5ead9","errorCode":null,"errorMessage":"Canonical nonce advanced without an authenticated signer transaction in the scanned canonical range","messagePattern":"Canonical nonce advanced without an authenticated signer transaction in the scanned canonical range","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":3054,"sourceCode":"        nonce: u64,\n        head: VerifiedBlockHeader,\n        authenticated_payloads: &HashMap<B256, Vec<u8>>,\n    ) -> anyhow::Result<Option<(B256, Vec<u8>)>> {\n        let wallet_address = self.wallet_address.to_string();\n        let cursor = self\n            .database\n            .load_execution_replacement_cursor(\n                intent.id,\n                self.chain_id,\n                &wallet_address,\n                nonce,\n                &self.manifest_digest,\n            )\n            .await?;\n        let start = cursor.as_ref().map_or(intent.created_block, |header| {\n            header.number.saturating_add(1)\n        });\n        anyhow::ensure!(\n            start <= head.number,\n            \"Canonical nonce advanced without an authenticated signer transaction in the scanned canonical range\"\n        );\n        let scan_range = replacement_scan_range(start, head.number)?;\n        let end = *scan_range.end();\n        let mut decisions = Vec::new();\n        let mut blocks = Vec::new();\n\n        if let Some(cursor) = cursor.as_ref() {\n            let parent = parse_verified_header(cursor)?;\n            let window = required_verification(\n                self.verification\n                    .verify_replacement_window(parent, end)\n                    .await,\n                \"canonical replacement window\",\n            )?;\n            decisions.push(verification_decision(&window, Some(start), Some(end)));\n            blocks = window.value;","sourceCodeStart":3036,"sourceCodeEnd":3072,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L3036-L3072","documentation":"scan_canonical_replacement() computes a scan start block (from a persisted replacement cursor or the intent's creation block) and requires that start be at or before the current canonical head. If the computed start is past the head, the canonical nonce advanced without any authenticated signer transaction being found in the scanned canonical range — an internal consistency violation meaning the ledger and chain state disagree.","triggerScenarios":"The durable replacement cursor (or intent.created_block) points to a block number greater than the current verified head: e.g. querying a lagging/replica RPC node, a reorg rewound the head, or a corrupted cursor row was loaded from the database.","commonSituations":"RPC provider failover to a lagging node; database cursor persisted against a different chain or manifest; deep chain reorg after the intent was created; clock/seed misconfiguration pointing at a testnet.","solutions":["Verify the RPC endpoint is fully synced (head block number matches network consensus)","Check the replacement cursor row in the database for the intent and correct or clear it so the scan restarts from intent.created_block","Confirm chain_id and network settings match the chain the intent was created on","If a reorg occurred, re-run reconciliation after the chain stabilizes"],"exampleFix":"// before\nlet head = provider.get_block_number().await?; // lagging replica\n// after\nlet head = provider.get_block_number().await;\nensure!(head >= cursor_block, \"RPC head lagging; retry with a synced node\");","handlingStrategy":"validation","validationCode":"let head = client.head_block_number().await?;\nlet start = cursor.map_or(intent.created_block, |h| h.number.saturating_add(1));\nif start > head {\n    return Err(\"scan start exceeds head; check RPC sync and cursor\");\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"authenticated signer transaction\") => resync_cursor_and_retry(),\n    other => other,\n}","preventionTips":["Monitor RPC head lag before reconciliation","Validate persisted cursors against the chain on startup","Use a single trusted node for head queries","Detect and handle reorgs before scanning"],"tags":["blockchain","reorg","consistency","reconciliation"],"backgroundTag":"internal-invariant-violation","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"}