nautechsystems/nautilus_trader · critical

Durable finalized header tip conflicts with independent sour

Error message

Durable finalized header tip conflicts with independent sources

What it means

The durable finalized tip persisted in the ledger is independently re-verified against the chain (`verify_block(durable_tip.number)`) and compared for exact equality with the stored header. A mismatch means the durable record disagrees with what the chain (via an independent verification source) reports for that height — a corrupted/incorrect ledger entry or a reorg past the recorded tip — so the client aborts rather than building ancestry on a false baseline.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:2547

            .database
            .load_execution_verification_position(
                self.chain_id,
                &wallet_address,
                &self.manifest_version,
                &self.manifest_digest,
            )
            .await?
            .ok_or_else(|| anyhow::anyhow!("Execution verification ledger is not initialized"))?;
        let durable_tip = parse_verified_header(&position.finalized_tip)?;
        anyhow::ensure!(
            durable_tip.number >= checkpoint.value.number && durable_tip.number <= target.number,
            "Pre-sign decision header does not extend the durable finalized header tip"
        );
        let durable_tip_verification = required_verification(
            self.verification.verify_block(durable_tip.number).await,
            "pre-sign durable finalized tip",
        )?;
        anyhow::ensure!(
            durable_tip_verification.value == durable_tip,
            "Durable finalized header tip conflicts with independent sources"
        );

        if durable_tip != checkpoint.value {
            decisions.push(verification_decision(
                &durable_tip_verification,
                Some(durable_tip.number),
                Some(durable_tip.number),
            ));
        }
        let mut cursor = durable_tip;
        while cursor.number < target.number {
            let end = cursor.number.saturating_add(4_096).min(target.number);
            let start = cursor.number.saturating_add(1);
            let ancestry = required_verification(
                self.verification.verify_header_window(cursor, end).await,
                "pre-sign decision ancestry",

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Investigate the mismatch: compare the stored tip against the chain's canonical block at that height to determine corruption vs reorg.
  2. If corruption is confirmed, re-initialize or repair the execution verification ledger row from verified chain data.
  3. Confirm the client and ledger use the same chain/RPC/network; mismatched endpoints produce contradictory headers.
  4. Treat recurrence as a serious integrity signal — halt signing until the ledger lineage is validated end to end.

Example fix

// before: trusting the stored tip blindly after a DB restore
let prepared = client.prepare_and_sign(intent).await?;
// after: validate the stored tip against the chain before resuming
verify_ledger_tip_matches_chain(chain_id, &wallet, &manifest_digest).await?;
let prepared = client.prepare_and_sign(intent).await?;
Defensive patterns

Strategy: validation

Validate before calling

pub async fn durable_tip_consistent(ver: &Verification, stored: &VerifiedBlockHeader) -> anyhow::Result<bool> {
    let live = ver.verify_block(stored.number).await?;
    Ok(&live.value == stored)
}

Try / catch

match prepare().await {
    Err(e) if e.to_string().contains("conflicts with independent sources") => {
        halt_signing("ledger tip integrity violation — manual investigation required");
        Err(e.into())
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling the pre-sign path when the stored `finalized_tip` header (hash/content) differs from the freshly verified header at the same height — e.g. ledger row written from bad data, a reorg that replaced the finalized tip's block, or cross-chain/wrong-database contamination of the row.

Common situations: A deep reorg invalidating what was believed finalized; manual database edits or restores from a different environment; a bug in the tip-parsing/persistence path storing an incorrect header; pointing the client at a different RPC/network than the one the ledger was built from.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/830b5763f0ae1d48. Report an issue: GitHub.