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)
.awaitView on GitHub (pinned to 18893faf8b)
Solutions
- Check database connectivity and retry; the transaction aborts cleanly on failure.
- Verify the database role has SELECT permission on execution_verification_nonce.
- Inspect Postgres logs for the underlying SQL error (timeout, permission, deadlock) at the failure time.
- 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
- Grant SELECT on execution_verification_nonce to the app role in migrations.
- Avoid idle-connection-killers between app and Postgres, or lower pool idle timeouts.
- Log the database error chain (via anyhow source) for diagnosis.
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
- Failed to lock intent for verified action: {e}
- Implement FromRow for FuturesSpread
- Implement FromRow for OptionSpread
- Execution schema version {} is newer than supported version
- Verified finalized transaction count advanced without an act
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ae7dc5693ea2cf53.
Report an issue: GitHub.