nautechsystems/nautilus_trader · error

Verified finalized height regressed below the durable finali

Error message

Verified finalized height regressed below the durable finalized header tip

What it means

The client fetches the newly verified finalized header for the receipt and requires it to be at or above the durable tip height. If verification reports a finalized height lower than what is already durable, finality has apparently regressed, which is impossible on a healthy chain and indicates a fork, misconfiguration, or corrupt verification source.

Source

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

        anyhow::ensure!(
            durable_tip.number >= checkpoint.number,
            "Durable finalized header tip precedes the trusted checkpoint"
        );
        let mut finalized_headers = vec![durable_tip];
        let durable_tip_verification = required_verification(
            self.verification.verify_block(durable_tip.number).await,
            "finality durable header tip",
        )?;
        anyhow::ensure!(
            durable_tip_verification.value == durable_tip,
            "Durable finalized header tip conflicts with independent sources"
        );
        decisions.push(verification_decision(
            &durable_tip_verification,
            Some(durable_tip.number),
            Some(durable_tip.number),
        ));
        anyhow::ensure!(
            finalized.number >= durable_tip.number,
            "Verified finalized height regressed below the durable finalized header tip"
        );
        let mut ancestry_cursor = durable_tip;
        while ancestry_cursor.number < finalized.number {
            let end = ancestry_cursor
                .number
                .saturating_add(4_096)
                .min(finalized.number);
            let start = ancestry_cursor.number.saturating_add(1);
            let ancestry_verification = required_verification(
                self.verification
                    .verify_header_window(ancestry_cursor, end)
                    .await,
                "finality ancestry",
            )?;
            let ancestry = &ancestry_verification.value;
            ancestry_cursor = *ancestry

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Halt processing; do not treat the receipt as finalized.
  2. Confirm the verification endpoint is on the same chain and fully synced.
  3. If a genuine deep reorg occurred, reset the ledger/checkpoint to a common ancestor and re-sync.

Example fix

// before: provider reports finalized=1150 but durable tip=1200
let finalized = provider.finalized_header()?;
anyhow::ensure!(finalized.number >= durable_tip.number, ...);
// after: guard with provider health check before running finality
ensure_provider_synced_and_same_chain(&provider, &chain_id)?;
Defensive patterns

Strategy: validation

Validate before calling

let finalized = provider.finalized_header().await?;
anyhow::ensure!(finalized.number >= ledger_tip_number, "finality regressed; possible deep reorg");

Try / catch

match result {
    Err(e) if e.to_string().contains("regressed below the durable") => {
        halt_finality_processing();
        investigate_reorg()?;
    }
    other => other,
}

Prevention

When it happens

Trigger: During finality verification of a receipt when the finality lookup yields a finalized header whose number < `durable_tip.number` — e.g. after a deep reorg or switching verification providers mid-run.

Common situations: Pointing the verification source at a lagging or different-chain endpoint; a catastrophic reorg invalidating previously finalized blocks; mixing ledger state with a fresh provider.

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


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