nautechsystems/nautilus_trader · critical
Verified finalized header conflicts with its ancestry window
Error message
Verified finalized header conflicts with its ancestry window
What it means
After replaying the ancestry window of headers between the durable finalized tip and the newly verified finalized header, the cursor must land exactly on the verified finalized header. If it does not, one of the intermediate headers breaks the chain of ancestry (hash linkage), meaning the verified header is not a descendant of the stored tip.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:6041
let start = ancestry_cursor.number.saturating_add(1);
let headers_verification = required_verification(
self.verification
.verify_header_window(ancestry_cursor, end)
.await,
"Blockchain finalized ancestry",
)?;
let headers = &headers_verification.value;
ancestry_cursor = *headers
.last()
.expect("nonempty ancestry window advances the cursor");
finalized_headers.extend(headers.iter().copied());
connect_decisions.push(verification_decision(
&headers_verification,
Some(start),
Some(end),
));
}
anyhow::ensure!(
ancestry_cursor == finalized,
"Verified finalized header conflicts with its ancestry window"
);
let nonce_verification = required_verification(
self.verification
.verify_transaction_count(&self.wallet_address, finalized.number)
.await,
"Blockchain finalized transaction count",
)?;
let observed_canonical_nonce = nonce_verification.value;
let next_canonical_nonce = position
.as_ref()
.map_or(observed_canonical_nonce, |position| {
position.next_canonical_nonce
});
if let Some(position) = position.as_ref() {
log::debug!(View on GitHub (pinned to 18893faf8b)
Solutions
- Rebuild the finalized header ancestry from the trusted checkpoint to discard reorged/corrupt headers.
- Verify the verification provider returns a consistent, hash-linked header chain (single provider, correct network).
- Check for mid-window reorgs and restart connection once finality stabilizes above the affected heights.
- Log/compare cursor hash vs finalized parent hash to locate the first divergent header before resyncing.
Example fix
// before: alternating providers across ancestry windows can yield unlinked headers provider = round_robin([rpc_a, rpc_b]) // after: use one consistent provider per connect provider = rpc_a
Defensive patterns
Strategy: validation
Validate before calling
let linked = ancestry.windows(2).all(|w| w[1].parent_hash == w[0].hash()); assert!(linked, "ancestry window is not hash-linked");
Type guard
fn ancestry_consistent(cursor: &Header, finalized: &Header) -> bool { cursor.hash() == finalized.hash() && cursor.number == finalized.number } Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("ancestry window") => rebuild_ancestry_from_checkpoint().await,
other => other.map(|_| ()),
} Prevention
- Use a single consistent verification provider per connect session
- Validate parent-hash linkage of fetched headers incrementally
- Rebuild ancestry from the trusted checkpoint after detected reorgs
- Cache headers with integrity checks (hash verification on read)
When it happens
Trigger: The while loop fetches consecutive header windows (verify via self.verification.verify_block / headers_verification decisions) from durable tip to finalized.number; the final ancestry_cursor != finalized, firing ensure!.
Common situations: A reorg replaced headers between the stored tip and the verified finalized height, an inconsistent verification provider returning headers that do not link, or corrupted cached headers within the ancestry window.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Decision header changed before signing
- Durable finalized header tip conflicts with independent sour
- Pool state block {} changed from {} to {}; refresh the profi
- Swap decision header conflicts with profiler ancestry
- Verified inclusion header does not match the finalized recei
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f1b0cc4dd41f90b2.
Report an issue: GitHub.