nautechsystems/nautilus_trader · error

Failed to read verified action nonce ledger: {e}

Error message

Failed to read verified action nonce ledger: {e}

What it means

Thrown when the SELECT on execution_verification_nonce (the canonical nonce ledger for the chain/wallet) fails with a database error. This is distinct from a missing ledger row (which yields 'Canonical nonce ledger is not initialized'); this error means the query itself errored.

Source

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

        let mut transaction = self
            .pool
            .begin()
            .await
            .map_err(|e| anyhow::anyhow!("Failed to start verified action evidence: {e}"))?;
        let (manifest_version, manifest_digest, revision) =
            sqlx::query_as::<_, (String, String, i64)>(
                "
                SELECT manifest_version, manifest_digest, revision
                FROM execution_verification_nonce
                WHERE chain_id = $1 AND wallet_address = $2
                FOR SHARE
                ",
            )
            .bind(chain_id)
            .bind(batch.wallet_address)
            .fetch_optional(&mut *transaction)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to read verified action nonce ledger: {e}"))?
            .ok_or_else(|| anyhow::anyhow!("Canonical nonce ledger is not initialized"))?;
        anyhow::ensure!(
            manifest_version == batch.manifest_version && manifest_digest == batch.manifest_digest,
            "Verified action manifest identity changed"
        );
        let intent_nonce = sqlx::query_scalar::<_, Option<i64>>(
            "
            SELECT nonce
            FROM execution_intent
            WHERE id = $1 AND chain_id = $2 AND wallet_address = $3 AND active
            FOR UPDATE
            ",
        )
        .bind(batch.intent_id)
        .bind(chain_id)
        .bind(batch.wallet_address)
        .fetch_optional(&mut *transaction)
        .await

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check database connectivity and retry; the transaction aborts cleanly on failure.
  2. Verify the database role has SELECT permission on execution_verification_nonce.
  3. Inspect Postgres logs for the underlying SQL error (timeout, permission, deadlock) at the failure time.
  4. Check for connection-terminating infrastructure (pgbouncer idle timeouts, proxies, k8s probes).

Example fix

// before: no permission check
let row = read_ledger(&db, chain_id, wallet).await?;
// after: fail fast with a privileged check
sqlx::query("SELECT 1 FROM execution_verification_nonce LIMIT 1").execute(&db).await.context("cannot read nonce ledger; check grants")?;
let row = read_ledger(&db, chain_id, wallet).await?;
Defensive patterns

Strategy: retry

Validate before calling

// Rust: verify read access to the ledger up front
sqlx::query("SELECT 1 FROM execution_verification_nonce LIMIT 1")
    .fetch_optional(&db).await
    .context("cannot read execution_verification_nonce; check grants")?;

Try / catch

// Rust
match record_batch().await {
    Err(e) if e.to_string().contains("Failed to read verified action nonce ledger") => {
        log_underlying(&e);
        retry_with_backoff(record_batch)
    }
    res => res,
}

Prevention

When it happens

Trigger: fetch_optional on the execution_verification_nonce SELECT returns Err — connection dropped, statement timeout, permission error on the table, or malformed query bindings.

Common situations: Role lacking SELECT privilege on execution_verification_nonce after a migration; connection pool connection killed by a proxy idle timeout; database failover during the read.

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/ae7dc5693ea2cf53. Report an issue: GitHub.