{"record":{"id":"b43b6a1081d15730","repo":"nautechsystems/nautilus_trader","slug":"finalized-header-conflicts-with-its-verified-ances","errorCode":null,"errorMessage":"Finalized header conflicts with its verified ancestry","messagePattern":"Finalized header conflicts with its verified ancestry","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":3479,"sourceCode":"            let start = ancestry_cursor.number.saturating_add(1);\n            let ancestry_verification = required_verification(\n                self.verification\n                    .verify_header_window(ancestry_cursor, end)\n                    .await,\n                \"finality ancestry\",\n            )?;\n            let ancestry = &ancestry_verification.value;\n            ancestry_cursor = *ancestry\n                .last()\n                .expect(\"nonempty finality ancestry advances the cursor\");\n            decisions.push(verification_decision(\n                &ancestry_verification,\n                Some(start),\n                Some(end),\n            ));\n            finalized_headers.extend(ancestry.iter().copied());\n        }\n        anyhow::ensure!(\n            ancestry_cursor == finalized,\n            \"Finalized header conflicts with its verified ancestry\"\n        );\n\n        let canonical_again_verification = required_verification(\n            self.verification.verify_block(receipt.block_number).await,\n            \"finality inclusion header reread\",\n        )?;\n        let canonical_again = canonical_again_verification.value;\n        let finalized_again_verification = required_verification(\n            self.verification.verify_block(finalized.number).await,\n            \"finalized header reread\",\n        )?;\n        let finalized_again = finalized_again_verification.value;\n        anyhow::ensure!(\n            canonical_again.hash == receipt.block_hash && finalized_again == finalized,\n            \"Finality verification disagreed with the receipt or finalized header\"\n        );","sourceCodeStart":3461,"sourceCodeEnd":3497,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L3461-L3497","documentation":"The client walks verified ancestry from the durable tip up to the finalized header and requires the cursor to land exactly on the finalized header. If the ancestry walk ends elsewhere, the claimed finalized header does not chain onto its own verified ancestry — a broken or forked link — so the finality claim is rejected.","triggerScenarios":"During ancestry construction: the loop from `durable_tip` toward `finalized.number` terminates but the final cursor header (`ancestry_cursor`) does not equal `finalized` — e.g. parent links in the fetched ancestry don't reach the finalized header (fork at some height within the range).","commonSituations":"Reorg inside the ancestry range while walking; provider returning headers from a fork; gaps or mismatched parent hashes in a custom verification source; fetching ancestry across an epoch boundary with a buggy provider.","solutions":["Compare parent hashes along the walked ancestry to find the fork point.","Re-fetch ancestry from the canonical provider and retry.","Reset finality state to before the fork point and resync."],"exampleFix":"// before: ancestry ends at a sibling header, not `finalized`\nensure!(ancestry_cursor == finalized, \"Finalized header conflicts with its verified ancestry\");\n// after: detect fork point before walking\nlet fork = find_fork(&ancestry, &finalized)?;\nif let Some(fork) = fork { resync_from(fork.number)?; }","handlingStrategy":"validation","validationCode":"let fork = find_fork_point(&ancestry, &finalized)?;\nanyhow::ensure!(fork.is_none(), \"ancestry forks before finalized header\");","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"conflicts with its verified ancestry\") => {\n        let fork = locate_fork()?;\n        reset_finality_to(fork.number)?;\n    }\n    other => other,\n}","preventionTips":["Use a single canonical provider for ancestry fetches","Log parent-hash chains during ancestry walks for post-mortems","Re-fetch ancestry on transient provider errors instead of persisting partial chains"],"tags":["finality","reorg","ancestry","consistency"],"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"}