nautechsystems/nautilus_trader · error · anyhow::Error
Failed to lock legacy execution transactions: {e}
Error message
Failed to lock legacy execution transactions: {e} What it means
Thrown when the LOCK TABLE execution_transaction IN ACCESS EXCLUSIVE MODE statement inside ensure_execution_transaction_schema fails. This exclusive lock fences older writers during the v2 migration; the wrapped error typically reports 'lock timeout', 'deadlock detected', 'relation "execution_transaction" does not exist', or a privilege failure. No DDL has run when this fires.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3054
/// The migration locks the legacy transaction table, refuses unresolved version 1 rows,
/// installs the versioned intent and hash-history tables, and fences older writers before
/// releasing the lock. This prevents a mixed-version process from bypassing the new signer
/// ownership constraints.
///
/// # Errors
///
/// Returns an error if the database operation fails.
pub async fn ensure_execution_transaction_schema(&self) -> anyhow::Result<()> {
let mut transaction = self
.pool
.begin()
.await
.map_err(|e| anyhow::anyhow!("Failed to start execution schema migration: {e}"))?;
sqlx::query("LOCK TABLE execution_transaction IN ACCESS EXCLUSIVE MODE")
.execute(&mut *transaction)
.await
.map_err(|e| anyhow::anyhow!("Failed to lock legacy execution transactions: {e}"))?;
for statement in [
"
ALTER TABLE execution_transaction
ADD COLUMN IF NOT EXISTS client_order_id TEXT
",
"
ALTER TABLE execution_transaction
ADD COLUMN IF NOT EXISTS wallet_address TEXT
",
"
ALTER TABLE execution_transaction
ALTER COLUMN wallet_address DROP NOT NULL
",
"
CREATE TABLE IF NOT EXISTS execution_schema_version (
component TEXT PRIMARY KEY,
version SMALLINT NOT NULL CHECK (version > 0)View on GitHub (pinned to 2114cf6f76)
Solutions
- Read the appended {e}: 'relation does not exist' means the v1 table is missing - point at the correct database or create the legacy table first
- Stop all old-version processes before migrating so the exclusive lock is granted immediately
- Raise or clear lock_timeout/statement_timeout for the migration session
- If blocked, find blockers in pg_stat_activity and terminate them, then re-run (the migration is idempotent)
Defensive patterns
Strategy: retry
Validate before calling
-- Confirm the legacy table exists and see blockers before migrating SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'execution_transaction'); SELECT pid, state, query FROM pg_stat_activity WHERE wait_event_type = 'Lock';
Try / catch
match db.ensure_execution_transaction_schema().await {
Err(e) => {
let msg = e.to_string();
if msg.contains("lock timeout") || msg.contains("deadlock") {
// retry after the blocking session finishes; migration is idempotent
} else if msg.contains("does not exist") {
// wrong database or missing v1 table - fix the target, do not retry
} else {
return Err(e);
}
}
Ok(()) => {}
} Prevention
- Quiesce old-version nodes before running the v2 migration
- Set a generous lock_timeout for the migration session only, then restore it
- Keep the migration on a direct connection rather than a transaction-pooling proxy
- Run migrations from a role that owns the execution_transaction table
When it happens
Trigger: Running the v2 migration while an old-version node still holds locks on execution_transaction; session lock_timeout/statement_timeout aborts the ACCESS EXCLUSIVE wait; a fresh database where the legacy v1 execution_transaction table was never created; role lacks privileges on the table.
Common situations: Rolling upgrade where old and new binaries overlap against one database; DBA-set lock_timeout; pointing the node at an empty database instead of the evolved one.
Related errors
- Failed to start execution schema migration: {e}
- Failed to migrate execution_transaction table: {e}
- Failed to read execution schema version: {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/369efd12dde7556c.
Report an issue: GitHub.