nautechsystems/nautilus_trader · error
Persisted intent chain ID {} does not match configured chain
Error message
Persisted intent chain ID {} does not match configured chain ID {} What it means
`validate_signed_transaction` checks that the chain ID persisted inside the intent (`intent_chain_id`) equals the chain ID the wallet/adapter was configured for (`intent.chain_id`). The library throws this when the durable intent was recorded for a different network than the one the adapter currently targets, preventing transactions intended for one chain from being replayed on another.
Source
Thrown at crates/adapters/blockchain/src/execution/transaction.rs:263
anyhow::ensure!(
tx.hash == intent.hash,
"Persisted transaction hash {} does not match signed transaction hash {}",
intent.hash,
tx.hash
);
anyhow::ensure!(
intent.durable_signer == intent.signer,
"Persisted transaction signer {} does not match configured wallet {}",
intent.durable_signer,
intent.signer
);
anyhow::ensure!(
tx.signer == intent.signer,
"Signed transaction signer {} does not match configured wallet {}",
tx.signer,
intent.signer
);
anyhow::ensure!(
intent.intent_chain_id == intent.chain_id,
"Persisted intent chain ID {} does not match configured chain ID {}",
intent.intent_chain_id,
intent.chain_id
);
anyhow::ensure!(
intent.row_chain_id == intent.chain_id,
"Persisted transaction row chain ID {} does not match configured chain ID {}",
intent.row_chain_id,
intent.chain_id
);
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
);View on GitHub (pinned to 18893faf8b)
Solutions
- Align the adapter's configured chain_id with the chain the intents were persisted for, or vice versa
- Re-create the intents under the current chain configuration (do not hand-edit persisted rows)
- Check the chain ID in your config/env (RPC endpoint and chain_id setting must agree) before processing persisted transactions
- If rows were copied from another environment, purge or migrate them explicitly rather than replaying
Example fix
// before (config drifted from persisted intent) // config: chain_id = 42161 (Arbitrum), row: intent_chain_id = 1 (mainnet) validate_signed_transaction(&raw, &intent)?; // ensure! fails // after: run the adapter against the chain the intent was created for // config: chain_id = 1, row: intent_chain_id = 1 validate_signed_transaction(&raw, &intent)?;
Defensive patterns
Strategy: validation
Validate before calling
if intent.intent_chain_id != intent.chain_id {
return Err(anyhow::anyhow!(
"intent chain {} != configured chain {}",
intent.intent_chain_id, intent.chain_id
));
} Type guard
fn intent_targets_configured_chain(intent: &SignedTransactionIntent) -> bool {
intent.intent_chain_id == intent.chain_id
} Try / catch
match authenticate_payload_identity_with_signer(&raw, &intent) {
Ok(()) => { /* proceed */ }
Err(e) if e.to_string().contains("Persisted intent chain ID") => {
// chain config drifted: halt replay and re-create intents for the current chain
}
Err(e) => return Err(e),
} Prevention
- Stamp intents with the chain ID from a single authoritative config source
- Fail fast at startup if the RPC endpoint's chain_id differs from the configured chain_id
- Purge or explicitly migrate intents when switching networks; never replay rows across chains
- Tag persisted rows with environment/chain metadata and verify on load
When it happens
Trigger: Calling `authenticate_payload_identity_with_signer` / `validate_signed_transaction` with an intent where `intent.intent_chain_id != intent.chain_id`. This is a pre-signature check on the persisted intent itself — no transaction bytes need to be malformed.
Common situations: Pointing the adapter at a different network (e.g. mainnet vs Sepolia vs an L2 like Arbitrum) after intents were persisted against the old chain; a config/env change of the chain ID while old database rows remain; copying database state between environments with different chain configurations.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Chain ID mismatch at connect: expected {expected_chain_id},
- Signed transaction chain ID {} does not match configured cha
- Unsupported blockchain {blockchain} for RPC connection
- Pool venue chain {blockchain} does not match the client chai
- Pool {instrument_id} tokens share a token priority; base and
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4fa009bde96ef821.
Report an issue: GitHub.