nautechsystems/nautilus_trader · error
A {} transaction is being prepared; at most one transaction
Error message
A {} transaction is being prepared; at most one transaction can be in flight What it means
The execution client enforces a strict single-transaction-in-flight model. This error is raised when a new transaction is attempted while the in-flight slot is occupied by a transaction still in the 'Preparing' phase; the message names the purpose currently preparing.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1851
finalized_headers: Vec<ExecutionVerifiedHeader>,
}
#[derive(Debug, Clone, Copy)]
enum TransactionAuthorization {
Wrap {
weth: Address,
},
Approve {
token: Address,
router: Address,
amount: U256,
},
}
/// The single-in-flight limit error naming the transaction currently occupying the slot.
fn in_flight_limit_error(slot: &InFlightSlot) -> anyhow::Error {
match slot {
InFlightSlot::Preparing(purpose) => anyhow::anyhow!(
"A {} transaction is being prepared; at most one transaction can be in flight",
purpose.as_str()
),
InFlightSlot::Recovering(recovery) => anyhow::anyhow!(
"Execution intent {} ({}, nonce {}) retains signer ownership pending recovery; at most one transaction can be in flight",
recovery.intent_id,
recovery.purpose.as_str(),
recovery.nonce
),
InFlightSlot::AwaitingFinality(in_flight) => anyhow::anyhow!(
"Transaction {} (intent {}, {}, nonce {}) is still awaiting finality; at most one transaction can be in flight",
in_flight.tx_hash,
in_flight.intent_id,
in_flight.purpose.as_str(),
in_flight.nonce
),
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Wait for the in-flight transaction to finish (poll its state or await completion) before submitting the next one.
- Serialize submissions: queue orders and process one at a time, or use one client per strategy thread.
- Recover the stuck preparation — if it never completes, use the recovery path to release the slot.
- Check RPC latency; slow eth_* calls extend the preparing window and increase collisions.
Example fix
// before: overlapping submissions client.submit_order(order_a)?; client.submit_order(order_b)?; // slot still held by a // after: await completion first client.submit_order(order_a)?; client.await_in_flight_complete().await?; client.submit_order(order_b)?;
Defensive patterns
Strategy: retry
Validate before calling
if client.in_flight_slot_occupied() { queue_order(order); return; } Try / catch
match client.submit_order(order) { Err(e) if e.to_string().contains("at most one transaction can be in flight") => { wait_for_slot().await; retry(order); } Ok(r) => r } Prevention
- Serialize order submissions through a queue
- Await completion of each transaction before the next submission
- Avoid sharing one client across concurrent threads
When it happens
Trigger: Calling submit_order (or any operation needing the slot) while a previous swap/wrap/approve transaction is still being prepared and has not completed or released the slot.
Common situations: Submitting orders too fast from a strategy loop; a prior preparation blocked on a slow RPC call holding the slot; concurrent threads sharing one client without synchronization.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Execution payload storage is not rolling back
- Execution intent {intent_id} is not prepared for nonce {nonc
- Execution intent {} ({}, nonce {}) retains signer ownership
- Transaction {} (intent {}, {}, nonce {}) is still awaiting f
- Failed to record prepared execution intent: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ce5512556c32fc54.
Report an issue: GitHub.