{"record":{"id":"d37d7fc68bf1d6cd","repo":"nautechsystems/nautilus_trader","slug":"replacement-scan-tip-conflicts-with-the-verified-c","errorCode":null,"errorMessage":"Replacement scan tip conflicts with the verified canonical head","messagePattern":"Replacement scan tip conflicts with the verified canonical head","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":3115,"sourceCode":"\n            if end > start {\n                let window = required_verification(\n                    self.verification\n                        .verify_replacement_window(start_header.value, end)\n                        .await,\n                    \"canonical replacement window\",\n                )?;\n                decisions.push(verification_decision(&window, Some(start + 1), Some(end)));\n                blocks.extend(window.value);\n            }\n        }\n\n        let scanned_tip = blocks\n            .last()\n            .map(|block| VerifiedBlockHeader::from(block.clone()))\n            .ok_or_else(|| anyhow::anyhow!(\"Verified replacement scan returned no blocks\"))?;\n        if end == head.number {\n            anyhow::ensure!(\n                scanned_tip == head,\n                \"Replacement scan tip conflicts with the verified canonical head\"\n            );\n        }\n        let mut candidates = blocks\n            .iter()\n            .flat_map(|block| block.transactions.iter())\n            .filter(|transaction| {\n                transaction.from == self.wallet_address && transaction.nonce == nonce\n            });\n        let candidate = candidates.next();\n        anyhow::ensure!(\n            candidates.next().is_none(),\n            \"Canonical replacement scan found duplicate signer-nonce transactions\"\n        );\n\n        let finalized_cursor = self\n            .database","sourceCodeStart":3097,"sourceCodeEnd":3133,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L3097-L3133","documentation":"When the replacement scan reaches the current verified head (end == head.number), the tip of the scanned block list must exactly equal the already-verified canonical head header. A mismatch means the scanned replacement history and the verified canonical head disagree — evidence of a reorg or an inconsistent data source.","triggerScenarios":"The last block returned by verify_replacement_window() has a different header than the verified head used to compute the scan end, i.e. the head moved (reorg) or the window fetch returned blocks from another branch.","commonSituations":"Chain reorg between fetching head and scanning; RPC load balancer serving different branches; stale cached head from the verification provider.","solutions":["Re-fetch the head and retry the scan after the chain stabilizes","Pin to a single consistent RPC endpoint for head and window queries","Persist/re-verify the head header before comparing with the scan tip","Investigate for a deep reorg if mismatches persist"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"let head = client.verified_head().await?;\nlet tip = scanned_blocks.last().map(VerifiedBlockHeader::from);\nif end == head.number && tip != Some(head) {\n    return Err(\"scan tip diverged from head; re-fetch and retry\");\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"conflicts with the verified canonical head\") => {\n        refetch_head_and_retry_with_backoff()\n    }\n    other => other,\n}","preventionTips":["Re-verify the head immediately before comparison","Avoid switching RPC nodes mid-scan","Add reorg detection before reconciliation","Delay scans near the head until blocks are finalized"],"tags":["blockchain","reorg","header-mismatch","consistency"],"backgroundTag":"checksum-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}