nautechsystems/nautilus_trader · error · anyhow::Error

No Postgres cache database is configured

Error message

No Postgres cache database is configured

What it means

After confirming the client is disconnected, payload_operation_database() falls back to a Postgres cache database taken from config.postgres_cache_database_config. If that option is None and the client's in-memory cache.database is also absent, there is no storage to operate on, so the call fails with this message.

Source

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

        database
            .rollback_execution_payload_storage(&keys, batch_size)
            .await
    }

    async fn payload_operation_database(&self) -> anyhow::Result<BlockchainCacheDatabase> {
        anyhow::ensure!(
            !self.core.is_connected(),
            "Disconnect the execution client before payload storage operations"
        );

        if let Some(database) = &self.cache.database {
            return Ok(database.clone());
        }
        let options = self
            .config
            .postgres_cache_database_config
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("No Postgres cache database is configured"))?;
        BlockchainCacheDatabase::connect(options.clone().into())
            .await
            .context("failed to connect to the execution database")
    }

    fn load_payload_keys(&self) -> anyhow::Result<Option<PayloadKeySet>> {
        PayloadKeySet::load(
            self.config.payload_key_env.as_deref(),
            &self.config.payload_key_retired_env,
            self.config.payload_deployment_id.as_deref(),
        )
    }

    fn payload_policy(&self) -> PayloadPolicy {
        PayloadPolicy {
            chain_id: self.chain.chain_id,
            signer: self.wallet_address,
            gas_limit: self.config.gas_limit,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set postgres_cache_database_config in the execution client config (connection options for BlockchainCacheDatabase).
  2. Construct the client with cache.database populated (durable store).
  3. Verify the config file/key spelling so the field actually deserializes.
  4. Run maintenance against the client instance that owns the cache database.

Example fix

// before
let config = ExecutionClientConfig::default(); // no postgres section
// after
let config = ExecutionClientConfig {
    postgres_cache_database_config: Some(PostgresCacheConfig::new(
        "postgres://user:pass@localhost:5432/nautilus",
    )),
    ..Default::default()
};
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(
    config.postgres_cache_database_config.is_some(),
    "configure postgres_cache_database_config for payload storage operations"
);

Prevention

When it happens

Trigger: Calling check/protect/rewrap/rollback payload storage on a client constructed without both a durable cache database and postgres_cache_database_config in its ExecutionClientConfig.

Common situations: Test or demo configs that omit the Postgres section; operators running maintenance against a client built without cache settings; typo'd config key so the field deserializes to None.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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