nautechsystems/nautilus_trader · error · anyhow::Error
No durable store configured; refusing to submit a transactio
Error message
No durable store configured; refusing to submit a transaction
What it means
BlockchainExecutionClient::transaction_executor (crates/adapters/blockchain/src/execution/client.rs:792) builds the shared TransactionExecutor and fails closed when self.cache.database is None - there is no durable store, so submitting, wrapping, or approving is refused. connect() attaches a Postgres store only when BlockchainExecutionClientConfig::postgres_cache_database_config is set, logging "No Postgres cache database configured; transactions will be refused (no durable store)" otherwise; the first transaction attempt then hits this error. Durable persistence of intents is a prerequisite for crash-safe execution, hence the refusal rather than a best-effort submit.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:792
})?;
if pool.token0.get_token_priority() == pool.token1.get_token_priority() {
anyhow::bail!(
"Pool {instrument_id} tokens share a token priority; base and quote orientation is ambiguous"
);
}
Ok(pool)
}
/// Builds the shared transaction executor from the connected client state.
///
/// # Errors
///
/// Returns an error if no durable store is configured or the signer is not initialized.
fn transaction_executor(&self) -> anyhow::Result<TransactionExecutor> {
let database = self.cache.database.clone().ok_or_else(|| {
anyhow::anyhow!("No durable store configured; refusing to submit a transaction")
})?;
let signer = self
.signer
.clone()
.ok_or_else(|| anyhow::anyhow!("Signer not initialized; connect the client first"))?;
Ok(TransactionExecutor {
http_rpc_client: self.http_rpc_client.clone(),
database,
signer,
in_flight: Arc::clone(&self.in_flight),
wallet_balance: Arc::clone(&self.wallet_balance),
account_id: self.core.account_id,
wallet_address: self.wallet_address,
chain_id: self.chain.chain_id,
max_fee_per_gas_wei: self.config.max_fee_per_gas_wei,
base_fee_buffer_bps: self.config.base_fee_buffer_bps,
gas_limit: self.config.gas_limit,View on GitHub (pinned to 2114cf6f76)
Solutions
- Set postgres_cache_database_config on BlockchainExecutionClientConfig with valid PostgresConnectOptions before building the client.
- Ensure connect() is called and returns Ok; it attaches the store and runs ensure_execution_transaction_schema.
- Check connect-time logs for "Failed to connect to the Postgres cache database" and fix credentials/host/port.
- Guard startup: refuse to trade when client.cache.has_database() is false.
Example fix
// before
let config = BlockchainExecutionClientConfig {
postgres_cache_database_config: None, // no durable store
..Default::default()
};
// connect() warns; first submit_order fails: "No durable store configured; refusing to submit a transaction"
// after
let config = BlockchainExecutionClientConfig {
postgres_cache_database_config: Some(postgres_connect_options),
..Default::default()
}; Defensive patterns
Strategy: validation
Validate before calling
// Rust: fail fast at startup when no durable store is attached
anyhow::ensure!(
client.cache.has_database(),
"execution client requires postgres_cache_database_config; refusing to start"
); Type guard
fn is_no_durable_store(e: &anyhow::Error) -> bool {
e.to_string().contains("No durable store configured; refusing to submit a transaction")
} Try / catch
match client.wrap(amount_wei).await {
Ok(hash) => hash,
Err(e) if is_no_durable_store(&e) => {
// configuration defect - stop trading rather than retry
return Err(e.context("set postgres_cache_database_config and reconnect"));
}
Err(e) => return Err(e),
} Prevention
- Make a Postgres store a hard requirement in the trading deployment's config validation.
- Alert on the connect() warning 'No Postgres cache database configured; transactions will be refused'.
- Run a pre-trade smoke test (tiny wrap or dry submission path) that fails fast on missing persistence.
When it happens
Trigger: BlockchainExecutionClientConfig built with postgres_cache_database_config: None and then wrap/approve/submit_order called; Postgres options present but connect() never invoked (or it failed at the Postgres step), leaving the cache without a store; a typo in the Postgres env vars making the config parser leave the field None.
Common situations: Missing POSTGRES_* environment variables in the deployment; a config file where the database section is commented out; swapping a production config for a local dev config that omits persistence.
Related errors
- No durable store configured; refusing to persist execution t
- No durable store configured for execution reconciliation
- No durable store configured; refusing to migrate execution t
- WS submit order failed: {e}
- WS cancel order failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/fa802a85783e9ed5.
Report an issue: GitHub.