nautechsystems/nautilus_trader · error

Signed transaction destination {} does not match persisted d

Error message

Signed transaction destination {} does not match persisted destination {}

What it means

`validate_signed_transaction` requires the signed transaction's `to` address to equal the destination persisted in the intent. A mismatch means the signed bytes call a different contract/address than the one that was approved, which the library treats as tampering or a wrong-payload bug and refuses to broadcast.

Source

Thrown at crates/adapters/blockchain/src/execution/transaction.rs:294

    anyhow::ensure!(
        tx.chain_id == u64::from(intent.chain_id),
        "Signed transaction chain ID {} does not match configured chain ID {}",
        tx.chain_id,
        intent.chain_id
    );
    anyhow::ensure!(
        tx.nonce == intent.nonce,
        "Signed transaction nonce {} does not match persisted nonce {}",
        tx.nonce,
        intent.nonce
    );
    anyhow::ensure!(
        tx.to == intent.to,
        "Signed transaction destination {} does not match persisted destination {}",
        tx.to,
        intent.to
    );
    anyhow::ensure!(
        tx.value == intent.value,
        "Signed transaction value does not match persisted value"
    );
    anyhow::ensure!(
        tx.input == intent.input,
        "Signed transaction calldata does not match persisted calldata"
    );
    anyhow::ensure!(
        tx.gas_limit <= intent.gas_limit,
        "Signed transaction gas limit {} exceeds configured ceiling {}",
        tx.gas_limit,
        intent.gas_limit
    );
    anyhow::ensure!(
        tx.max_fee_per_gas <= u128::from(intent.max_fee_per_gas),
        "Signed transaction max fee per gas {} wei exceeds configured ceiling {} wei",
        tx.max_fee_per_gas,
        intent.max_fee_per_gas

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-sign against the exact destination in the persisted intent (`intent.to`) and validate the fresh bytes.
  2. Confirm signer and intent-creation code resolve the contract address from the same configuration source.
  3. Regenerate the signed payload after any contract redeployment or proxy address change; old signatures are invalid.
  4. If bytes are unexpectedly foreign, trace where the raw transaction was produced — it did not come from this system's signer.

Example fix

// before
let tx = TransactionRequest::new().to(other_contract_address);
let signed = sign(&tx, &wallet);
validate_signed_transaction(&signed, &intent)?; // destination mismatch

// after
let tx = TransactionRequest::new().to(intent.to);
let signed = sign(&tx, &wallet);
validate_signed_transaction(&signed, &intent)?;
Defensive patterns

Strategy: validation

Validate before calling

fn destination_matches(raw: &[u8], intent: &SignedTransactionIntent) -> bool {
    decode_signed_transaction(raw).map(|tx| tx.to == intent.to).unwrap_or(false)
}

Type guard

fn has_expected_destination(d: &DecodedSignedTransaction, i: &SignedTransactionIntent) -> bool {
    d.to == i.to
}

Try / catch

validate_signed_transaction(&raw, &intent).map_err(|e| {
    if e.to_string().contains("destination") { Error::WrongTarget(e) } else { Error::Validation(e) }
})?;

Prevention

When it happens

Trigger: `validate_signed_transaction` decodes signed bytes whose `TxKind::Call` destination differs from `intent.to` — e.g. the signer encoded a different target address, or the persisted intent points at a new deployment while old signed bytes target the old address.

Common situations: Contract address changed between environments (testnet vs mainnet deployment, proxy upgrade) while old signed blobs were reused, config supplying a different contract address to the signer than to the intent writer, or hand-crafted/replayed bytes from another chain or fork.

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/155d44925f33d606. Report an issue: GitHub.