{"record":{"id":"cb1188863131ee0c","repo":"nautechsystems/nautilus_trader","slug":"persisted-terminal-transaction-tx-hash-is-not-st","errorCode":null,"errorMessage":"Persisted terminal transaction {tx_hash} is not stable at the finalized boundary","messagePattern":"Persisted terminal transaction (.+?) is not stable at the finalized boundary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1357,"sourceCode":"                        Some(InFlightSlot::AwaitingFinality(InFlightTransaction {\n                            intent_id: intent.id,\n                            nonce,\n                            tx_hash: replacement_hash,\n                            purpose,\n                        }));\n                }\n            }\n        }\n        let outcome = if finality_already_committed {\n            let receipt = verified_value(\n                executor.verification.verify_receipt(&tx_hash).await,\n                \"persisted terminal receipt\",\n            )?;\n            let finality = executor\n                .receipt_is_stably_finalized(&receipt)\n                .await?\n                .ok_or_else(|| {\n                    anyhow::anyhow!(\n                        \"Persisted terminal transaction {tx_hash} is not stable at the finalized boundary\"\n                    )\n                })?;\n            let included = IncludedTransaction {\n                intent_id: intent.id,\n                nonce,\n                tx_hash,\n                block_number: receipt.block_number,\n                receipt,\n                finality,\n            };\n\n            if intent.status == \"finalized\" {\n                InclusionOutcome::Finalized(included)\n            } else {\n                InclusionOutcome::Reverted(included)\n            }\n        } else {","sourceCodeStart":1339,"sourceCodeEnd":1375,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L1339-L1375","documentation":"When reconciling a persisted terminal (final-status) transaction, the adapter looks up the receipt and asks the executor whether it is stably finalized. If the receipt exists but finality cannot be confirmed at the finalized boundary (None returned), reconciliation aborts rather than treating an unstable terminal tx as included.","triggerScenarios":"`connect()` -> `reconcile_unresolved_execution()` encounters an intent with a terminal tx_hash; `receipt_is_stably_finalized(&receipt)` returns None (e.g. reorg observed, receipt finality status below the configured boundary).","commonSituations":"Chain reorg moved the tx off the finalized block; RPC endpoint lagging on finality; terminal status persisted too early after a fast confirmation heuristic; misconfigured finality threshold.","solutions":["Wait/retry reconciliation until the chain finalizes the block containing the tx (reorg resolution)","Verify the RPC provider reports the receipt as finalized; switch to a healthier/faster finality-tracking endpoint","Investigate why the intent reached terminal status before finality; delay terminal marking until `receipt_is_stably_finalized` confirms","If the tx was genuinely reorged out, reset the intent to a non-terminal state and rebroadcast"],"exampleFix":"// before: marking intent terminal immediately after first receipt\nmark_terminal(intent, receipt);\n// after: only mark terminal once stable at finalized boundary\nif let Some(_) = executor.receipt_is_stably_finalized(&receipt).await? {\n    mark_terminal(intent, receipt);\n}","handlingStrategy":"retry","validationCode":"if let Some(receipt) = fetch_receipt(tx_hash).await? {\n    if executor.receipt_is_stably_finalized(&receipt).await?.is_none() {\n        // defer reconciliation until finality\n    }\n}","typeGuard":"async fn is_stably_finalized(executor: &Executor, receipt: &Receipt) -> bool {\n    executor.receipt_is_stably_finalized(receipt).await.map(|o| o.is_some()).unwrap_or(false)\n}","tryCatchPattern":"loop {\n    match reconcile(intent).await {\n        Err(e) if e.to_string().contains(\"not stable at the finalized boundary\") => {\n            tokio::time::sleep(Duration::from_secs(12)).await; // retry after a block\n        }\n        r => break r,\n    }\n}","preventionTips":["Only mark intents terminal after confirmed finality","Use RPC providers with reliable finality tracking","Account for possible reorgs before trusting fast receipts"],"tags":["blockchain","finality","reorg","reconciliation"],"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-23T08:17:48.524Z"}