nautechsystems/nautilus_trader · error

{context} verification is locally invalid

Error message

{context} verification is locally invalid

What it means

Raised when the verification outcome is LocallyInvalid: the verification result violates a local precondition or validation rule (the data came back but fails local checks). The library bails because proceeding would violate its own invariants about what a valid verification looks like.

Source

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

}

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],
) -> anyhow::Result<()> {
    match authorization {
        None => Ok(()),
        Some(TransactionAuthorization::Wrap { weth }) => {
            anyhow::ensure!(
                to == *weth && !value.is_zero() && input == WETH9::depositCall::SELECTOR,
                "Wrap authorization does not match the transaction call"
            );
            Ok(())

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the LocallyInvalid payload to find which local validation failed
  2. Re-sync local state (nonce, chain id, balances) with the chain
  3. Update decoder/ABI definitions if the node response format changed
  4. Switch to a different RPC provider and compare responses
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate expected response shape before trusting verification
let decoded = decode_receipt(&raw);
anyhow::ensure!(decoded.status <= 1, "unexpected receipt status field");

Type guard

fn is_valid_receipt(r: &RawReceipt) -> bool {
    r.status.is_some() && r.block_number.is_some()
}

Try / catch

match res {
    Err(e) if e.to_string().contains("verification is locally invalid") => {
        // inspect payload, re-sync local state, do not blind-retry
    }
    r => r?,
}

Prevention

When it happens

Trigger: A verification check returns VerificationOutcome::LocallyInvalid — e.g. the returned value fails local decoding/validation, a receipt field is malformed, or the verified value contradicts locally computed expectations.

Common situations: Node returning malformed or unexpected response payloads; ABI/decoder version mismatch producing invalid decoded data; local state (nonce, chain id) out of sync with the network.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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