nautechsystems/nautilus_trader · critical · anyhow::Error
Execution verification manifest identity changed
Error message
Execution verification manifest identity changed
What it means
Raised in database.rs:3712 when the persisted verification nonce row's manifest_version or manifest_digest do not match the digest/version of the manifest the caller is using. The manifest is the identity of the verification rules and contract set; a mismatch means the stored verification state was produced under a different manifest and is not interchangeable with the current one.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3712
);
let chain_id =
i32::try_from(chain_id).context("Verification chain ID exceeds PostgreSQL INTEGER")?;
let current = sqlx::query_as::<_, (String, String, i64, i64)>(
"
SELECT manifest_version, manifest_digest, next_canonical_nonce, revision
FROM execution_verification_nonce
WHERE chain_id = $1 AND wallet_address = $2
",
)
.bind(chain_id)
.bind(wallet_address)
.fetch_optional(&self.pool)
.await
.context("failed to load execution verification nonce position")?;
let Some((stored_version, stored_digest, nonce, revision)) = current else {
return Ok(None);
};
anyhow::ensure!(
stored_version == manifest_version && stored_digest == manifest_digest,
"Execution verification manifest identity changed"
);
let row = sqlx::query_as::<_, (i64, String, String, i64, Option<String>, String)>(
"
SELECT number, hash, parent_hash, timestamp, base_fee_per_gas, manifest_digest
FROM execution_verified_finalized_header
WHERE chain_id = $1 AND wallet_address = $2
ORDER BY number DESC
LIMIT 1
",
)
.bind(chain_id)
.bind(wallet_address)
.fetch_optional(&self.pool)
.await
.context("failed to load verified finalized header tip")?
.ok_or_else(|| anyhow::anyhow!("Verified finalized header ledger is empty"))?;View on GitHub (pinned to 18893faf8b)
Solutions
- Re-bootstrap the verification state for this wallet/chain so the stored manifest matches the current one.
- Verify the manifest version and digest your deployment passes match the values used when the database was initialized.
- If the manifest change was accidental, revert the manifest configuration to the digest stored in execution_verification_nonce.
- Wipe/rotate verification state for the affected wallet deliberately (with the prior nonce accounted for) rather than editing rows ad hoc.
Example fix
// before: manifest config edited -> digest mismatch let pos = db.load_execution_verification_position(chain, wallet, "v1", &old_digest).await; // after: pass the manifest identity that matches the stored state, or re-bootstrap let (ver, digest) = current_manifest_identity(); assert_eq!((ver, digest), stored_manifest_identity(&db, chain, wallet)?); let pos = db.load_execution_verification_position(chain, wallet, &ver, &digest).await?;
Defensive patterns
Strategy: validation
Validate before calling
let stored: Option<(String, String)> = sqlx::query_as(
"SELECT manifest_version, manifest_digest FROM execution_verification_nonce \
WHERE chain_id = $1 AND wallet_address = $2",
).bind(chain_id).bind(wallet).fetch_optional(&pool).await?;
if let Some((v, d)) = stored {
assert_eq!((v.as_str(), d.as_str()), (manifest_version, manifest_digest),
"manifest identity drifted; re-bootstrap required");
} Try / catch
match load_position(...).await {
Err(e) if e.to_string().contains("manifest identity changed") => {
// halt verification for this wallet; re-bootstrap under the new manifest
},
other => other?,
} Prevention
- Treat the verification manifest as immutable per deployment; version it explicitly
- Persist the new manifest digest and re-bootstrap atomically when the manifest changes
- Never share one database between deployments with different manifests
When it happens
Trigger: Calling load_execution_verification_position with manifest_version/manifest_digest arguments that differ from the (manifest_version, manifest_digest) stored in execution_verification_nonce for the given chain_id and wallet_address.
Common situations: Changing the verification manifest (adding/changing verified contracts or rules) without re-bootstrapping the wallet's verification state; pointing the node at a database initialized for a different deployment configuration; wallet previously verified under a different manifest revision.
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
- Finalized header manifest identity changed
- Verified finalized header ledger is empty
- Verified nonce assignment manifest identity changed
- Signed transaction {transaction_hash} conflicts with its per
- Verified finalized header ledger mismatch for height {number
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f2ae8e555c404dc8.
Report an issue: GitHub.