{"record":{"id":"ff90768d3dab4904","repo":"nautechsystems/nautilus_trader","slug":"pre-sign-decision-header-does-not-extend-the-durab","errorCode":null,"errorMessage":"Pre-sign decision header does not extend the durable finalized header tip","messagePattern":"Pre-sign decision header does not extend the durable finalized header tip","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":2539,"sourceCode":"        );\n        let mut decisions = vec![verification_decision(\n            &checkpoint,\n            Some(checkpoint.value.number),\n            Some(checkpoint.value.number),\n        )];\n        let wallet_address = self.wallet_address.to_string();\n        let position = self\n            .database\n            .load_execution_verification_position(\n                self.chain_id,\n                &wallet_address,\n                &self.manifest_version,\n                &self.manifest_digest,\n            )\n            .await?\n            .ok_or_else(|| anyhow::anyhow!(\"Execution verification ledger is not initialized\"))?;\n        let durable_tip = parse_verified_header(&position.finalized_tip)?;\n        anyhow::ensure!(\n            durable_tip.number >= checkpoint.value.number && durable_tip.number <= target.number,\n            \"Pre-sign decision header does not extend the durable finalized header tip\"\n        );\n        let durable_tip_verification = required_verification(\n            self.verification.verify_block(durable_tip.number).await,\n            \"pre-sign durable finalized tip\",\n        )?;\n        anyhow::ensure!(\n            durable_tip_verification.value == durable_tip,\n            \"Durable finalized header tip conflicts with independent sources\"\n        );\n\n        if durable_tip != checkpoint.value {\n            decisions.push(verification_decision(\n                &durable_tip_verification,\n                Some(durable_tip.number),\n                Some(durable_tip.number),\n            ));","sourceCodeStart":2521,"sourceCodeEnd":2557,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L2521-L2557","documentation":"After loading the durable finalized tip from the ledger, the client requires it to sit within the verified window: at or after the trusted checkpoint and at or before the decision header. This proves the persisted ancestry baseline is usable to connect the checkpoint to the decision block. A tip outside that range indicates the ledger is stale (behind checkpoint) or corrupted/ahead (beyond the decision block), so the client aborts.","triggerScenarios":"Calling the pre-sign path when the persisted `finalized_tip` is older than the current verified checkpoint (ledger fell behind, e.g. after downtime) or newer than the decision header (decision header from stale anchors, or a corrupted/incorrectly parsed tip).","commonSituations":"Operator downtime during which the ledger stopped advancing while checkpoints moved on; database restored from an old backup; stale swap anchors making the decision header older than the durable tip; manifest rotation leaving the tip from another lineage.","solutions":["Let the ledger catch up: run the header-verification/ledger advance loop until finalized_tip is >= checkpoint, then retry.","Refresh the decision header/anchors so the decision block is at or after the durable tip.","Inspect the ledger row for corruption or a wrong-lineage tip (e.g. after restoring a backup) and re-initialize if needed.","Confirm the same (chain, wallet, manifest) identity is used by both the ledger writer and this signing client."],"exampleFix":"// before: signing after long downtime without catching up the ledger\nlet prepared = client.prepare_and_sign(intent).await?; // durable_tip.number < checkpoint.number\n// after: advance ledger to head first\nledger.catch_up_to_finalized().await?;\nlet prepared = client.prepare_and_sign(intent).await?;","handlingStrategy":"retry","validationCode":"pub fn tip_in_window(tip_number: u64, checkpoint_number: u64, decision_number: u64) -> bool {\n    tip_number >= checkpoint_number && tip_number <= decision_number\n}","typeGuard":null,"tryCatchPattern":"match prepare().await {\n    Err(e) if e.to_string().contains(\"does not extend the durable finalized header tip\") => {\n        ledger.catch_up_to_finalized().await?;\n        prepare().await\n    }\n    other => other?,\n}","preventionTips":["Keep the ledger advance loop running continuously; alert if it lags the checkpoint.","After downtime, always catch the ledger up before resuming signing.","Refresh decision headers when they may predate the durable tip."],"tags":["blockchain","ledger","stale-state","checkpoint"],"backgroundTag":"invalid-state-transition","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"}