nautechsystems/nautilus_trader · error

Finality status conflicts with the verified transaction rece

Error message

Finality status conflicts with the verified transaction receipt

What it means

Before committing a verified finality outcome, `commit_verified_finality` requires the status to be Finalized or Reverted AND to agree with the receipt's execution status stored on `included.receipt` (true == finalized/success, false == reverted). A mismatch between the finality status and the on-chain receipt means the outcome cannot be committed consistently.

Source

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

            ),
        ]);
        Ok(Some(StableFinality {
            decisions,
            inclusion_header: durable_verified_header(&canonical_again),
            finalized_headers: finalized_headers
                .iter()
                .map(durable_verified_header)
                .collect(),
        }))
    }

    async fn commit_verified_finality(
        &self,
        included: &IncludedTransaction,
        status: TransactionStatus,
        verified_postconditions: &[ExecutionVerificationDecision],
    ) -> anyhow::Result<()> {
        anyhow::ensure!(
            matches!(
                status,
                TransactionStatus::Finalized | TransactionStatus::Reverted
            ) && included.receipt.status == (status == TransactionStatus::Finalized),
            "Finality status conflicts with the verified transaction receipt"
        );
        let mut decisions = included.finality.decisions.clone();
        decisions.extend_from_slice(verified_postconditions);
        let wallet_address = self.wallet_address.to_string();
        let transaction_hash = included.tx_hash.to_string();
        let block_hash = included.receipt.block_hash.to_string();
        let effective_gas_price = included.receipt.effective_gas_price.to_string();
        self.database
            .record_execution_finality_verified(&ExecutionFinalityTransition {
                intent_id: included.intent_id,
                chain_id: self.chain_id,
                wallet_address: &wallet_address,
                nonce: included.nonce,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-fetch the transaction receipt and recompute the status from `receipt.status` before committing.
  2. Ensure the status mapping only produces Finalized/Reverted for terminal receipts.
  3. Verify the receipt is from the canonical, finalized block before deriving status.

Example fix

// before: status guessed from logs
let status = if logs.is_empty() { TransactionStatus::Reverted } else { TransactionStatus::Finalized };
// after: derive from receipt
let status = if included.receipt.status { TransactionStatus::Finalized } else { TransactionStatus::Reverted };
Defensive patterns

Strategy: type-guard

Validate before calling

let valid = matches!(status, TransactionStatus::Finalized | TransactionStatus::Reverted)
    && included.receipt.status == (status == TransactionStatus::Finalized);
anyhow::ensure!(valid, "status does not match receipt");

Type guard

fn is_terminal_status_agreeing_with_receipt(status: &TransactionStatus, receipt_status: bool) -> bool {
    matches!(status, TransactionStatus::Finalized | TransactionStatus::Reverted)
        && receipt_status == (*status == TransactionStatus::Finalized)
}

Try / catch

match result {
    Err(e) if e.to_string().contains("conflicts with the verified transaction receipt") => {
        refetch_receipt_and_recompute_status(included).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling finality handling with a status like Pending/Confirmed instead of Finalized|Reverted, or reporting Finalized for a transaction whose receipt `status == false` (reverted), or Reverted for a successful receipt.

Common situations: Upstream adapter mapping receipt status incorrectly; race where status was fetched before the transaction's terminal state; mixing status enums from different provider versions.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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