{"record":{"id":"fa802a85783e9ed5","repo":"nautechsystems/nautilus_trader","slug":"no-durable-store-configured-refusing-to-submit-a","errorCode":null,"errorMessage":"No durable store configured; refusing to submit a transaction","messagePattern":"No durable store configured; refusing to submit a transaction","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":792,"sourceCode":"            })?;\n\n        if pool.token0.get_token_priority() == pool.token1.get_token_priority() {\n            anyhow::bail!(\n                \"Pool {instrument_id} tokens share a token priority; base and quote orientation is ambiguous\"\n            );\n        }\n\n        Ok(pool)\n    }\n\n    /// Builds the shared transaction executor from the connected client state.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if no durable store is configured or the signer is not initialized.\n    fn transaction_executor(&self) -> anyhow::Result<TransactionExecutor> {\n        let database = self.cache.database.clone().ok_or_else(|| {\n            anyhow::anyhow!(\"No durable store configured; refusing to submit a transaction\")\n        })?;\n        let signer = self\n            .signer\n            .clone()\n            .ok_or_else(|| anyhow::anyhow!(\"Signer not initialized; connect the client first\"))?;\n\n        Ok(TransactionExecutor {\n            http_rpc_client: self.http_rpc_client.clone(),\n            database,\n            signer,\n            in_flight: Arc::clone(&self.in_flight),\n            wallet_balance: Arc::clone(&self.wallet_balance),\n            account_id: self.core.account_id,\n            wallet_address: self.wallet_address,\n            chain_id: self.chain.chain_id,\n            max_fee_per_gas_wei: self.config.max_fee_per_gas_wei,\n            base_fee_buffer_bps: self.config.base_fee_buffer_bps,\n            gas_limit: self.config.gas_limit,","sourceCodeStart":774,"sourceCodeEnd":810,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/execution/client.rs#L774-L810","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet config = BlockchainExecutionClientConfig {\n    postgres_cache_database_config: None, // no durable store\n    ..Default::default()\n};\n// connect() warns; first submit_order fails: \"No durable store configured; refusing to submit a transaction\"\n\n// after\nlet config = BlockchainExecutionClientConfig {\n    postgres_cache_database_config: Some(postgres_connect_options),\n    ..Default::default()\n};","handlingStrategy":"validation","validationCode":"// Rust: fail fast at startup when no durable store is attached\nanyhow::ensure!(\n    client.cache.has_database(),\n    \"execution client requires postgres_cache_database_config; refusing to start\"\n);","typeGuard":"fn is_no_durable_store(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"No durable store configured; refusing to submit a transaction\")\n}","tryCatchPattern":"match client.wrap(amount_wei).await {\n    Ok(hash) => hash,\n    Err(e) if is_no_durable_store(&e) => {\n        // configuration defect - stop trading rather than retry\n        return Err(e.context(\"set postgres_cache_database_config and reconnect\"));\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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."],"tags":["postgres","configuration","execution","durable-store","rust"],"backgroundTag":"database-not-configured","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}