nautechsystems/nautilus_trader · error · anyhow::Error
Verification migration was supplied for an initialized signe
Error message
Verification migration was supplied for an initialized signer
What it means
The nonce ledger already has an initialized row for this (chain_id, wallet_address), meaning the signer has been bootstrapped before. A migration payload in the bootstrap request would re-initialize or transform signer state, which is only legal for a fresh/uninitialized signer, so the code rejects it to protect the existing durable nonce history.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:4023
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
FOR UPDATE
",
)
.bind(chain_id)
.bind(bootstrap.wallet_address)
.fetch_optional(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to read canonical nonce ledger: {e}"))?;
let initialized = current.is_some();
let revision = if let Some((manifest_version, manifest_digest, stored_nonce, revision)) =
current
{
anyhow::ensure!(
bootstrap.migration.is_none(),
"Verification migration was supplied for an initialized signer"
);
anyhow::ensure!(
manifest_version == bootstrap.manifest_version
&& manifest_digest == bootstrap.manifest_digest,
"Execution verification manifest identity changed"
);
anyhow::ensure!(
stored_nonce == next_canonical_nonce,
"Canonical nonce ledger changed during verification bootstrap"
);
if observed_canonical_nonce != stored_nonce {
let expected_observed_nonce = stored_nonce
.checked_add(1)
.ok_or_else(|| anyhow::anyhow!("Canonical nonce overflow"))?;
anyhow::ensure!(View on GitHub (pinned to 18893faf8b)
Solutions
- Remove the migration parameter from the bootstrap request for this wallet — it is already initialized
- Use a fresh wallet_address if a migration-backed initialization is truly intended
- Verify chain_id/wallet_address match the intended signer; a typo can make an initialized signer appear at the wrong key
- If state is genuinely corrupted, follow the project's documented recovery procedure rather than re-migrating
Example fix
// before
let bootstrap = Bootstrap { manifest_version, manifest_digest, migration: Some(mig), .. };
// after (wallet already initialized)
let bootstrap = Bootstrap { manifest_version, manifest_digest, migration: None, .. }; Defensive patterns
Strategy: validation
Validate before calling
// Only include a migration when the signer row is absent
let initialized = sqlx::query_scalar::<_, i32>(
"SELECT 1 FROM execution_verification_nonce
WHERE chain_id=$1 AND wallet_address=$2")
.bind(chain_id).bind(wallet)
.fetch_optional(&mut *conn).await?.is_some();
let migration_opt = if initialized { None } else { Some(migration) }; Try / catch
match bootstrap_signer(req).await {
Err(e) if e.to_string().contains("Verification migration was supplied for an initialized signer") => {
warn!(wallet = %req.wallet, "already initialized; dropping migration and retrying");
bootstrap_signer(Bootstrap { migration: None, ..req }).await
}
other => other,
} Prevention
- Treat bootstrap-with-migration as a one-time, fresh-wallet-only operation
- Keep a registry of initialized (chain_id, wallet) pairs before running setup scripts
- Validate wallet_address/chain_id inputs to avoid typos hitting the wrong signer row
- Never reuse an initialization script against production after staging runs with the same wallet
When it happens
Trigger: Calling the verification bootstrap with bootstrap.migration = Some(..) for a chain_id/wallet_address whose execution_verification_nonce row already exists.
Common situations: Re-running an initial-setup script (that includes a migration parameter) against an already-initialized signer; copy-pasting a bootstrap config from a new wallet to an existing one; pointing a migration job at production after it ran in staging with the same wallet.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Verified finalized transaction count advanced without an act
- Unknown execution event marker {event}
- Failed to read canonical nonce ledger: {e}
- Verified finalized transaction count is outside the owned re
- Execution payload storage is in {} maintenance
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3df1a3143f395730.
Report an issue: GitHub.