nautechsystems/nautilus_trader · error · anyhow::Error

Failed to read canonical nonce ledger: {e}

Error message

Failed to read canonical nonce ledger: {e}

What it means

Bootstrap reads the durable canonical nonce ledger row (manifest_version, manifest_digest, next_canonical_nonce, revision) for (chain_id, wallet_address) from execution_verification_nonce. Any database failure of this SELECT is wrapped in this error; it is distinct from the row simply not existing (which means the signer is uninitialized).

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:4017

            anyhow::ensure!(
                installed_version <= VERIFICATION_SCHEMA_VERSION,
                "Execution verification schema version {installed_version} is newer than supported version {VERIFICATION_SCHEMA_VERSION}"
            );
        }

        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"
            );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the execution_verification_nonce table exists (run the schema install step)
  2. Check grants for the connecting DB role on execution_verification_nonce
  3. Retry after transient connection failures
  4. Confirm the database URL/environment is the intended one

Example fix

// before: wrong env DB
DATABASE_URL=postgres://staging-db/nautilus
// after: correct env
DATABASE_URL=postgres://prod-db/nautilus
Defensive patterns

Strategy: validation

Validate before calling

let exists: Option<i16> = sqlx::query_scalar(
  "SELECT 1 FROM information_schema.tables
   WHERE table_name='execution_verification_nonce'")
  .fetch_optional(&mut *conn).await?;
if exists.is_none() { install_verification_schema(&mut conn).await?; }
let has_select = sqlx::query_scalar::<_, bool>(
  "SELECT has_table_privilege(current_user,'execution_verification_nonce','SELECT')")
  .fetch_one(&mut *conn).await?;
anyhow::ensure!(has_select, "app role lacks SELECT on execution_verification_nonce");

Try / catch

match read_nonce_ledger(&mut tx, chain_id, wallet).await {
    Err(e) if is_transient_db_error(&e) => retry_with_backoff(3, || read_nonce_ledger(&mut tx, chain_id, wallet)),
    Err(e) => return Err(e),
    Ok(row) => row,
}

Prevention

When it happens

Trigger: The SELECT ... FROM execution_verification_nonce WHERE chain_id=$1 AND wallet_address=$2 FOR UPDATE fails: table missing, connection error, permissions, or transient Postgres failure during the locked bootstrap transaction.

Common situations: Verification schema never installed on this database; DB credentials/grants changed; transient connection drop during startup; querying with a database URL pointing at the wrong environment.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/17806826059df4a8. Report an issue: GitHub.