nautechsystems/nautilus_trader · error

No durable store configured; refusing to submit a {} transac

Error message

No durable store configured; refusing to submit a {} transaction

What it means

ensure_transaction_ready refuses to submit any transaction when the execution client has no durable (database-backed) store configured. The durable store is required to persist in-flight transaction state so transactions can be recovered and tracked across restarts. Without it the client deliberately refuses to broadcast rather than risk untracked transactions.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:1533

                unreachable!("swap intents restore a swap plan")
            }
        }
    }

    fn ensure_transaction_ready(&self, purpose: TransactionPurpose) -> anyhow::Result<()> {
        if !self.core.is_connected() {
            anyhow::bail!("Blockchain execution client is not connected");
        }

        {
            let slot = self.in_flight.lock();
            if let Some(in_flight) = *slot {
                return Err(in_flight_limit_error(&in_flight));
            }
        }

        if !self.cache.has_database() {
            anyhow::bail!(
                "No durable store configured; refusing to submit a {} transaction",
                purpose.as_str()
            );
        }
        Ok(())
    }

    /// Validates a submit-order command against the configured policy and builds the swap plan.
    ///
    /// Local checks run first: pool resolution, order semantics, allowlists, amount and
    /// slippage limits, and the quote derived from the live pool profiler. Infrastructure
    /// readiness (connection, in-flight slot, durable store, signer) follows. Chain state is
    /// verified in the spawned task before signing.
    fn prepare_swap(&self, cmd: &SubmitOrder, order: &OrderAny) -> anyhow::Result<SwapPlan> {
        let instrument_id = order.instrument_id();
        let pool = self.resolve_pool(&instrument_id)?;

        if order.order_type() != OrderType::Market {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Configure a durable database-backed cache for the execution client (e.g. set the cache/database path in the adapter/live config) before submitting transactions.
  2. If running in a non-persistence context intentionally, use a dry-run or backtest execution path that does not call submit_order/approve/wrap.
  3. Verify has_database() at startup and fail fast with a clear config error instead of at trade time.

Example fix

// before
let client = BlockchainExecutionClient::new(cache, exec_client_config(None));
client.submit_order(cmd)?; // panics/errors: no durable store
// after
let client = BlockchainExecutionClient::new(
    cache,
    exec_client_config(Some(DatabaseConfig::with_path("./data/live.db"))),
);
client.submit_order(cmd)?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust
if !client.cache_has_database() {
    return Err(anyhow::anyhow!(
        "durable store not configured; configure a database-backed cache before trading"
    ));
}

Prevention

When it happens

Trigger: Calling submit_order (via prepare_swap), approve, or wrap when `self.cache.has_database()` returns false — i.e. the cache was constructed without a database backing store.

Common situations: Running the blockchain execution client in-memory for backtests or quick tests and then submitting live transactions; forgetting to configure the database/cache path in the adapter config; a misconfigured environment where the cache database fails to initialize silently.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4a1251a174097ac1. Report an issue: GitHub.