nautechsystems/nautilus_trader · error

{context} verification disagreed

Error message

{context} verification disagreed

What it means

This error comes from a helper that converts a VerificationOutcome into a Result. When the post-transaction verification outcome is Disagreement, it means an independent on-chain check (e.g. balance change, receipt status) disagreed with what the local simulation predicted. The library refuses to accept the transaction result because the two sources of truth conflict.

Source

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

enum ReconciliationAuthorization {
    Rebroadcast,
    Retain,
    ScanReplacement(VerifiedBlockHeader),
}

fn verified_value<T>(outcome: VerificationOutcome<T>, context: &str) -> anyhow::Result<T> {
    required_verification(outcome, context).map(|verified| verified.value)
}

fn required_verification<T>(
    outcome: VerificationOutcome<T>,
    context: &str,
) -> anyhow::Result<Verified<T>> {
    match outcome {
        VerificationOutcome::Verified(verified) => Ok(verified),
        VerificationOutcome::Disagreement(_) => {
            anyhow::bail!("{context} verification disagreed")
        }
        VerificationOutcome::Unavailable(_) => {
            anyhow::bail!("{context} verification is unavailable")
        }
        VerificationOutcome::Retryable(_) => {
            anyhow::bail!("{context} verification is retryable")
        }
        VerificationOutcome::LocallyInvalid(_) => {
            anyhow::bail!("{context} verification is locally invalid")
        }
    }
}

fn validate_transaction_authorization(
    authorization: Option<&TransactionAuthorization>,
    to: Address,
    value: U256,
    input: &[u8],

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-fetch on-chain state and re-run the transaction with a fresh simulation
  2. Check the RPC provider for stale/behind nodes and use a consistent endpoint
  3. Re-verify allowances, balances, and approvals before resubmitting
  4. Inspect the disagreement payload (carried in the outcome) to identify which check diverged
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check consistency before submitting
let sim = client.simulate_swap(&pool, amount).await?;
let onchain = client.fetch_pool_state(&pool).await?;
assert_eq!(sim.block_state_root, onchain.state_root, "state diverged before submit");

Try / catch

match res {
    Err(e) if e.to_string().ends_with("verification disagreed") => {
        // refresh state, re-simulate, and decide whether to resubmit
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling the verify helper (used across pre-sign checks like swap simulation, balance, allowance) when the verification backend returns VerificationOutcome::Disagreement — i.e. the simulated/expected result conflicts with actual on-chain state.

Common situations: State changed between simulation and execution (another transaction consumed the same allowance or moved funds); RPC node returning stale or divergent data; MEV/sandwich altering the outcome vs simulation.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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