nautechsystems/nautilus_trader · error · anyhow::Error

Persisted terminal transaction {tx_hash} is not stable at th

Error message

Persisted terminal transaction {tx_hash} is not stable at the finalized boundary

What it means

For a persisted terminal transaction, receipt_is_stably_finalized() re-derived finality and it failed: either the node's finalized block number is still below the receipt's block number, or re-fetching the receipt's block and the finalized block produced hashes different from the ones first observed. The ensure! converts that instability into a hard error instead of trusting the persisted 'finalized'/'reverted' status.

Source

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

        let executor = self.transaction_executor()?;
        let prepared = PreparedTransaction {
            intent_id: intent.id,
            created_block: intent.created_block,
            nonce,
            tx_hash,
            raw_tx: current.raw_transaction.clone().unwrap_or_default(),
        };
        let outcome = if matches!(intent.status.as_str(), "finalized" | "reverted") {
            let receipt = executor
                .http_rpc_client
                .get_transaction_receipt(&tx_hash)
                .await?
                .ok_or_else(|| {
                    anyhow::anyhow!(
                        "Finalized execution transaction {tx_hash} no longer has a receipt"
                    )
                })?;
            anyhow::ensure!(
                executor.receipt_is_stably_finalized(&receipt).await?,
                "Persisted terminal transaction {tx_hash} is not stable at the finalized boundary"
            );

            if intent.status == "finalized" {
                InclusionOutcome::Finalized(IncludedTransaction {
                    intent_id: intent.id,
                    tx_hash,
                    block_number: receipt.block_number,
                    receipt,
                })
            } else {
                InclusionOutcome::Reverted(tx_hash)
            }
        } else {
            executor.await_finality(&prepared).await?
        };

View on GitHub (pinned to 2114cf6f76)

Solutions

  1. Retry connect()/reconciliation after the node catches up — finality lag is usually transient
  2. Query the node directly: eth_getBlockByNumber('finalized') and compare its number/hash against the receipt's blockNumber/blockHash
  3. If it persists, switch to a reputable, canonical RPC provider and reconcile again
  4. Only if on-chain state is independently verified should you repair the intent row manually

Example fix

# before: fail-fast single attempt during a finality blip
client.connect()  # raises: not stable at the finalized boundary

# after: retry with backoff until the node view stabilizes
for attempt in range(5):
    try:
        client.connect()
        break
    except Exception as e:
        if "finalized boundary" not in str(e):
            raise
        time.sleep(10 * (attempt + 1))
Defensive patterns

Strategy: retry

Validate before calling

from web3 import Web3

w3 = Web3(Web3.HTTPProvider(rpc_url))
finalized = w3.eth.get_block('finalized')
receipt = w3.eth.get_transaction_receipt(tx_hash)
stable = (finalized.number >= receipt.blockNumber)
assert stable, 'node finality lags the receipt; retry connect later'

Try / catch

for attempt in range(6):
    try:
        client.connect()
        break
    except Exception as e:
        if 'finalized boundary' not in str(e):
            raise
        time.sleep(15 * (attempt + 1))  # let the node's finalized tag catch up
else:
    raise RuntimeError('reconciliation never stabilized')

Prevention

When it happens

Trigger: Startup reconciliation of a 'finalized'/'reverted' intent while the RPC endpoint lags on finality, serves a non-canonical view, or the chain actually reorganized blocks that were previously reported finalized.

Common situations: Aggressively-load-balanced or self-hosted nodes with inconsistent fork state; reconnecting right after a network incident; querying nodes whose 'finalized' tag trails the actual finalized height.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21). Data as JSON: /api/errors/cb1188863131ee0c. Report an issue: GitHub.