nautechsystems/nautilus_trader · error

Coinbase credentials not available; set COINBASE_API_KEY and

Error message

Coinbase credentials not available; set COINBASE_API_KEY and COINBASE_API_SECRET or pass them in the config

What it means

The execution (trading) client requires Coinbase API credentials. `new` resolves them from the config or the COINBASE_API_KEY / COINBASE_API_SECRET environment variables; if neither is available it raises this error and refuses to start.

Source

Thrown at crates/adapters/coinbase/src/execution.rs:148

    /// Creates a new [`CoinbaseExecutionClient`].
    ///
    /// # Errors
    ///
    /// Returns an error if credentials cannot be resolved or the underlying
    /// HTTP / WebSocket client cannot be constructed.
    pub fn new(
        core: ExecutionClientCore,
        config: CoinbaseExecutionClientConfig,
    ) -> anyhow::Result<Self> {
        let credential = CoinbaseCredential::resolve(
            config.api_key.as_ref().map(|value| value.expose_secret()),
            config
                .api_secret
                .as_ref()
                .map(|value| value.expose_secret()),
        )
        .ok_or_else(|| {
                    anyhow::anyhow!(
                        "Coinbase credentials not available; set COINBASE_API_KEY and COINBASE_API_SECRET or pass them in the config"
                    )
                })?;
        let proxy_url = config
            .proxy_url
            .as_ref()
            .map(|value| value.expose_secret().to_owned());

        let retry_config = RetryConfig {
            max_retries: config.max_retries,
            initial_delay_ms: config.retry_delay_initial_ms,
            max_delay_ms: config.retry_delay_max_ms,
            backoff_factor: 2.0,
            jitter_ms: 250,
            operation_timeout_ms: Some(60_000),
            immediate_first: false,
            max_elapsed_ms: Some(180_000),
        };

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set COINBASE_API_KEY and COINBASE_API_SECRET in the environment
  2. Pass api_key and api_secret explicitly in the execution client config
  3. Verify the .env file is actually loaded (e.g. dotenv import) before construction
  4. Check the secret is non-empty (a set-but-empty env var still fails)
  5. Confirm the process user can read the env/secret source

Example fix

// before
let config = CoinbaseExecClientConfig::default(); // no creds, no env vars
// after
std::env::set_var("COINBASE_API_KEY", key);
std::env::set_var("COINBASE_API_SECRET", secret);
let client = CoinbaseExecClient::new(...)?;
Defensive patterns

Strategy: validation

Validate before calling

fn have_coinbase_creds(cfg: &Config) -> bool {
    let from_cfg = cfg.api_key.is_some() && cfg.api_secret.is_some();
    let from_env = std::env::var("COINBASE_API_KEY").map_or(false, |v| !v.is_empty())
        && std::env::var("COINBASE_API_SECRET").map_or(false, |v| !v.is_empty());
    from_cfg || from_env
}
if !have_coinbase_creds(&config) { return Err("set COINBASE_API_KEY/SECRET"); }

Prevention

When it happens

Trigger: Constructing the Coinbase execution client with api_key/api_secret unset in the config and the env vars missing or empty in the process environment.

Common situations: Deploying a trading node without a .env file loaded; running in a container where the secret env vars were not passed; passing only the API key but not the secret (or vice versa).

Related errors


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