nautechsystems/nautilus_trader · error
Persisted transaction row chain ID {} does not match configu
Error message
Persisted transaction row chain ID {} does not match configured chain ID {} What it means
`validate_signed_transaction` also verifies that the chain ID stored on the persisted transaction row (`intent.row_chain_id`) matches the configured chain ID. This is a third-way consistency check: the intent body, the durable row metadata, and the adapter configuration must all agree on the target network, catching partially-updated or corrupted persisted state even before touching the signed bytes.
Source
Thrown at crates/adapters/blockchain/src/execution/transaction.rs:269
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
);
anyhow::ensure!(
tx.nonce == intent.nonce,
"Signed transaction nonce {} does not match persisted nonce {}",
tx.nonce,
intent.nonce
);View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the failing row's chain_id column and the adapter config; determine which is authoritative
- Re-persist the transaction/intent through the normal write path so row_chain_id is written from the current configuration
- Fix the persistence/migration code that wrote the wrong row_chain_id, then regenerate the affected rows
- Purge rows imported from a different chain environment instead of replaying them
Example fix
// before: row written with stale chain id // row: row_chain_id = 5 (Goerli), config: chain_id = 1 validate_signed_transaction(&raw, &intent)?; // ensure! fails // after: re-persist the row under the current configuration let row = persist_intent(&intent, configured_chain_id); // row_chain_id = 1 validate_signed_transaction(&raw, &intent)?;
Defensive patterns
Strategy: validation
Validate before calling
if intent.row_chain_id != intent.chain_id {
return Err(anyhow::anyhow!(
"row chain {} != configured chain {}",
intent.row_chain_id, intent.chain_id
));
} Type guard
fn row_matches_configured_chain(intent: &SignedTransactionIntent) -> bool {
intent.row_chain_id == intent.chain_id
} Try / catch
match authenticate_payload_identity_with_signer(&raw, &intent) {
Ok(()) => { /* proceed */ }
Err(e) if e.to_string().contains("row chain ID") => {
// persisted row corruption/partial migration: quarantine and re-persist the row
}
Err(e) => return Err(e),
} Prevention
- Write row_chain_id from the same code path that writes intent_chain_id so they cannot diverge
- Use DB constraints or a write-side check that row_chain_id equals the configured chain
- Audit migrations for columns that backfill chain metadata
- Alert on any row whose stored chain ID differs from the environment's chain
When it happens
Trigger: Calling `authenticate_payload_identity_with_signer` / `validate_signed_transaction` with an intent where `intent.row_chain_id != intent.chain_id`, i.e. the database row's chain ID column disagrees with the configured network.
Common situations: A partial migration or bug during intent persistence wrote the wrong chain ID into the row; rows copied from another environment/database; a schema change or backfill that left row_chain_id stale after the configured chain changed; manual DB edits.
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
- Verified finalized transaction count advanced without an act
- Verified finalized transaction count is outside the owned re
- Verified finalized header extension does not start at the du
- Finalized header ledger conflicts at height {}
- Replacement scan cursor {} is not durably finalized
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c2aec9bb8a3b6a64.
Report an issue: GitHub.