nautechsystems/nautilus_trader · critical
Execution schema version
Error message
Execution schema version {} is newer than supported version {EXECUTION_SCHEMA_VERSION} What it means
The blockchain adapter's execution cache database stores a schema version; on open, if the on-disk execution schema version is greater than EXECUTION_SCHEMA_VERSION compiled into this binary, opening is aborted. Downgrading the library (running an older binary against a database written by a newer one) would risk misreading or corrupting the schema.
Solutions
- Upgrade the library back to the version (or newer) that wrote the database so its schema version is supported
- Move/rename the existing cache database file so a fresh one is created at the old schema version (loses cached data)
- If the data is dispensable, delete the cache database and let it rebuild from the chain
- Check the installed version row in the database to confirm which version created it before deciding
Example fix
// before: opening old binary against migrated DB
let db = ExecutionDatabase::open(path).await?; // bails: schema too new
// after: detect and start fresh
match ExecutionDatabase::open(path).await {
Ok(db) => db,
Err(e) if e.to_string().contains("newer than supported") => {
fs::rename(path, path.with_extension("db.newer-schema"))?;
ExecutionDatabase::open(path).await?
}
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
fn is_schema_too_new(err: &anyhow::Error) -> bool {
err.to_string().contains("newer than supported version")
}
// check before opening: if cache file exists and was written by a newer build, relocate it first Try / catch
let db = match ExecutionDatabase::open(path).await {
Ok(db) => db,
Err(e) if e.to_string().contains("newer than supported version") => {
warn!("cache written by newer build; recreating at old schema");
std::fs::rename(&path, path.with_extension("db.incompatible"))?;
ExecutionDatabase::open(path).await?
}
Err(e) => return Err(e.into()),
}; Prevention
- Pin one library version per cache database location; don't share cache files across versions
- When rolling back versions, relocate or delete the cache DB first
- Back up cache files with the creating version in the filename
- Read the schema-version row before opening if you need to detect version mismatches proactively
When it happens
Trigger: Opening the blockchain execution cache database (database.rs execution open path) after switching from a newer version of nautilus_blockchain back to an older one, so installed_version > EXECUTION_SCHEMA_VERSION.
Common situations: Rolling back a deployment or checking out an older git branch while the SQLite/DB file was migrated by a newer build; sharing one cache file across machines with different library versions; restoring a backup created by newer software.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Execution intent uses unsupported schema version
- Execution payload protocol version
- Execution verification schema version
- Finalized nonce does not match canonical nonce
- Unsupported execution verification schema version
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c6693c843e348452.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3600
] {
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)
.await
.map_err(|e| anyhow::anyhow!("Failed to inspect legacy execution transactions: {e}"))?;
anyhow::ensure!(
unresolved_legacy == 0,
"Cannot safely migrate {unresolved_legacy} unresolved execution schema version 1 transaction(s); resolve them with the prior version before enabling version {EXECUTION_SCHEMA_VERSION}"View on GitHub (pinned to 18893faf8b)