nautechsystems/nautilus_trader · error · anyhow::Error

Failed to read verification schema version: {e}

Error message

Failed to read verification schema version: {e}

What it means

After locking the verification tables, bootstrap reads the installed schema version from execution_schema_version for component 'evm_execution_verification'. This error wraps any database failure of that SELECT (connection error, missing table, permissions), as opposed to the version being merely absent or too new.

Source

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

        }

        sqlx::query(
            "LOCK TABLE execution_intent, execution_transaction_hash, \
             execution_verification_nonce, execution_verified_finalized_header, \
             execution_verification_decision, execution_replacement_scan \
             IN ACCESS EXCLUSIVE MODE",
        )
        .execute(&mut *transaction)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to lock execution verification state: {e}"))?;

        let installed_version = sqlx::query_scalar::<_, i16>(
            "SELECT version FROM execution_schema_version \
             WHERE component = 'evm_execution_verification'",
        )
        .fetch_optional(&mut *transaction)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to read verification schema version: {e}"))?;
        if let Some(installed_version) = installed_version {
            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)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the base schema including execution_schema_version was installed before this bootstrap runs
  2. Check the DB user has SELECT on execution_schema_version
  3. Retry on transient connection errors
  4. Inspect the inner sqlx error for the precise cause (undefined_table vs connection error)

Example fix

// before: assuming schema exists
bootstrap_verification(pool).await?;
// after: install base schema first
ensure_base_schema(pool).await?; // creates execution_schema_version if missing
bootstrap_verification(pool).await?;
Defensive patterns

Strategy: validation

Validate before calling

let exists: Option<i16> = sqlx::query_scalar(
  "SELECT 1 FROM information_schema.tables
   WHERE table_name='execution_schema_version'")
  .fetch_optional(&mut *conn).await?;
if exists.is_none() { install_base_schema(&mut conn).await?; }

Try / catch

match read_schema_version(&mut tx).await {
    Err(e) if is_transient_db_error(&e) => retry_with_backoff(3, || read_schema_version(&mut tx)),
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: The SELECT version FROM execution_schema_version WHERE component='evm_execution_verification' query fails: table does not exist (base schema not installed), connection dropped, insufficient privileges, or a transient Postgres error.

Common situations: Running verification bootstrap against a database where only a partial/older schema exists; revoked SELECT grants; transient DB restarts or failover during startup.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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