nautechsystems/nautilus_trader · error · anyhow::Error
Failed to read execution schema version: {e}
Error message
Failed to read execution schema version: {e} What it means
Thrown when the SELECT of version for component 'evm_execution' from execution_schema_version fails inside ensure_execution_transaction_schema, immediately after the DDL loop. Because that table was just created with IF NOT EXISTS in the same transaction, this almost always indicates a transport-level failure (dropped connection, statement timeout) rather than a missing relation.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3228
)),
UNIQUE (intent_id, transition_key)
)
",
] {
sqlx::query(statement)
.execute(&mut *transaction)
.await
.map_err(|e| {
anyhow::anyhow!("Failed to migrate execution_transaction table: {e}")
})?;
}
let installed_version = sqlx::query_scalar::<_, i16>(
"SELECT version FROM execution_schema_version WHERE component = 'evm_execution'",
)
.fetch_optional(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to read execution schema version: {e}"))?;
if let Some(installed_version) = installed_version
&& installed_version > EXECUTION_SCHEMA_VERSION
{
anyhow::bail!(
"Execution schema version {} is newer than supported version {EXECUTION_SCHEMA_VERSION}",
installed_version
);
}
let unresolved_legacy = sqlx::query_scalar::<_, i64>(
"
SELECT COUNT(*)
FROM execution_transaction
WHERE status IN ('pending', 'included', 'reverted')
",
)
.fetch_one(&mut *transaction)
.awaitView on GitHub (pinned to 2114cf6f76)
Solutions
- Confirm network stability to Postgres and re-run - the whole migration is idempotent (IF NOT EXISTS / ON CONFLICT / OR REPLACE)
- Raise statement_timeout for the migration session
- If a proxy like PgBouncer sits in the path, run the migration over a direct or session-pooled connection
Defensive patterns
Strategy: retry
Validate before calling
// Health check immediately before the migration to reduce mid-flight transport failures
let healthy = sqlx::query("SELECT 1").execute(&pool).await.is_ok(); Try / catch
for attempt in 0..3 {
match db.ensure_execution_transaction_schema().await {
Ok(()) => break,
Err(e) if e.downcast_ref::<sqlx::Error>().is_some_and(|se| matches!(se, sqlx::Error::Io(_) | sqlx::Error::ConnectionClosed(_))) => {
tokio::time::sleep(Duration::from_secs(1u64 << attempt)).await;
}
Err(e) => return Err(e),
}
} Prevention
- Run the migration over a stable direct connection, not through transaction-pooling proxies
- Raise statement_timeout for the migration session
- Keep migration windows away from scheduled failovers or maintenance
When it happens
Trigger: Connection reset between the DDL loop and the version read; statement_timeout firing on the migration session; a pooling proxy killing the session mid-transaction.
Common situations: Flaky network path to a managed Postgres; aggressive statement_timeout; failover during migration.
Related errors
- Failed to start execution schema migration: {e}
- Failed to lock legacy execution transactions: {e}
- Failed to migrate execution_transaction table: {e}
- Failed to inspect legacy execution transactions: {e}
- Cannot safely migrate {unresolved_legacy} unresolved executi
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/2c03433f5844605f.
Report an issue: GitHub.