nautechsystems/nautilus_trader · error · anyhow::Error
Failed to start execution intent reservation: {e}
Error message
Failed to start execution intent reservation: {e} What it means
Thrown when reserve_execution_intent fails at pool.begin(), before the intent INSERT runs. As with other begin failures, the wrapped sqlx error means a connection could not be acquired: database unreachable, pool exhausted by concurrent activity, or a dropped connection. No signer slot or client order is touched when this fires.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:3324
///
/// # Errors
///
/// Returns an error if the signer or client order is already owned, or persistence fails.
pub async fn reserve_execution_intent(
&self,
intent: &ExecutionIntentInsert,
) -> anyhow::Result<ExecutionIntentRow> {
let chain_id = i32::try_from(intent.chain_id)
.with_context(|| format!("Chain ID {} exceeds PostgreSQL INTEGER", intent.chain_id))?;
let created_block = i64::try_from(intent.created_block).with_context(|| {
format!(
"Execution creation block {} exceeds PostgreSQL BIGINT",
intent.created_block
)
})?;
let mut transaction =
self.pool.begin().await.map_err(|e| {
anyhow::anyhow!("Failed to start execution intent reservation: {e}")
})?;
let row = sqlx::query_as::<_, ExecutionIntentRow>(
"
INSERT INTO execution_intent (
schema_version, chain_id, wallet_address, purpose, status,
client_order_id, trader_id, strategy_id, account_id, instrument_id,
pool_address, transaction_to, transaction_input, transaction_value,
amount_in, created_block
)
VALUES ($1, $2, $3, $4, 'prepared', $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
RETURNING
id, schema_version, chain_id, wallet_address, nonce, purpose, status,
client_order_id, trader_id, strategy_id, account_id, instrument_id,
pool_address, transaction_to, transaction_input, transaction_value,
amount_in, created_block, acknowledgement_emitted, fill_emitted,
terminal_emitted, active
",
)View on GitHub (pinned to 2114cf6f76)
Solutions
- Verify database health (SELECT 1) and network connectivity
- Increase pool max_connections and acquire_timeout to cover peak concurrency
- Bound concurrent reservations with a semaphore so begin() never starves
- Retry only after transient connection failures - a successful reserve is exactly-once ownership, not an idempotent write
Defensive patterns
Strategy: retry
Validate before calling
// Cheap liveness probe before attempting a reservation under load
let ok = sqlx::query("SELECT 1").execute(&pool).await.is_ok(); Try / catch
match db.reserve_execution_intent(&intent).await {
Err(e) if e.downcast_ref::<sqlx::Error>() == Some(&sqlx::Error::PoolTimedOut) => {
// shed load or expand the pool, then retry; nothing was reserved
}
other => other?,
} Prevention
- Bound concurrent reservations with a semaphore sized below pool capacity
- Tune max_connections and acquire_timeout for peak trade bursts
- Reserve before building/signing the transaction so a begin() failure costs nothing
When it happens
Trigger: Reserving intents while the pool is fully checked out by receipt recorders; database restart mid-trading; acquire_timeout shorter than load spikes allow.
Common situations: Trade bursts exhaust pool capacity; a connection leak elsewhere; failover of the database tier.
Related errors
- Failed to start execution schema migration: {e}
- Failed to reserve execution intent for signer {} on chain {}
- Failed to record prepared execution intent: {e}
- Failed to commit execution intent reservation: {e}
- Failed to start recoverable execution transition: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/940b209b3ae938c1.
Report an issue: GitHub.