nautechsystems/nautilus_trader · error

Receipt verification is locally invalid for transaction {tx_

Error message

Receipt verification is locally invalid for transaction {tx_hash}

What it means

During receipt-based finality polling, the verification layer returned VerificationOutcome::LocallyInvalid for the transaction, meaning the fetched receipt contradicts locally-held expectations (e.g. receipt fields disagree with the signed transaction or local record). The client bails out rather than treating the tx as confirmed.

Source

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

                    }
                }
                VerificationOutcome::Retryable(_) => {
                    continue;
                }
                VerificationOutcome::Disagreement(_) => {
                    return Ok(InclusionOutcome::Pending(format!(
                        "Receipt verification disagreed for transaction {tx_hash}; the intent stays occupied for reconciliation"
                    )));
                }
                VerificationOutcome::Unavailable(_) => {
                    log::warn!(
                        "Finality poll {}/{} for transaction {tx_hash} was unavailable",
                        attempt + 1,
                        self.receipt_max_polls
                    );
                }
                VerificationOutcome::LocallyInvalid(_) => {
                    anyhow::bail!(
                        "Receipt verification is locally invalid for transaction {tx_hash}"
                    );
                }
            }
        }

        self.database
            .record_execution_status(
                prepared.intent_id,
                &tx_hash.to_string(),
                TransactionStatus::Dropped,
                None,
                None,
                None,
                None,
                None,
            )
            .await?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the RPC endpoint and chain ID match the intended network
  2. Re-fetch the receipt manually and compare block number, status, and hash against the signed transaction
  3. Switch to a trusted/redundant RPC provider
  4. Re-check whether the tx was replaced (e.g. by a same-nonce resubmission) and restart finality tracking for the new tx

Example fix

// before: single flaky endpoint
let client = ExecutionClient::new(rpc_url);
// after: validated endpoint with matching chain id
assert_eq!(client.chain_id().await?, expected_chain_id);
let client = ExecutionClient::new(verified_rpc_url);
Defensive patterns

Strategy: retry

Validate before calling

let receipt = rpc.get_receipt(tx_hash).await?;
assert_eq!(receipt.transaction_hash, tx_hash, "receipt does not match requested tx hash");

Try / catch

match res {
    Err(e) if e.to_string().contains("locally invalid") => {
        switch_to_backup_rpc();
        reverify_receipt(tx_hash)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Polling a transaction receipt to finality when the returned receipt fails local validation — wrong status, mismatched block/hash versus the signed tx, or a receipt from a different transaction than tx_hash under an unreliable provider.

Common situations: Misbehaving or misconfigured RPC endpoint returning inconsistent receipts; tx was replayed/replaced (same hash on a forked chain); querying the wrong network/chain ID so the hash resolves to an unrelated receipt.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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