nautechsystems/nautilus_trader · error · anyhow::Error

BitMEX execution client requires API key and secret

Error message

BitMEX execution client requires API key and secret

What it means

The BitMEX execution client constructor requires API credentials; BitmexExecutionClientConfig::has_api_credentials must be true. If the API key and/or secret is absent, new() bails rather than constructing a client that cannot authenticate.

Source

Thrown at crates/adapters/bitmex/src/execution.rs:129

            LogLevel::Warning => log::warn!("{message}"),
            LogLevel::Error => log::error!("{message}"),
        }
    }

    /// Creates a new [`BitmexExecutionClient`].
    ///
    /// # Errors
    ///
    /// Returns an error if the broadcaster pool sizes are invalid, API credentials are unavailable,
    /// or either the HTTP or WebSocket client fails to construct.
    pub fn new(
        mut core: ExecutionClientCore,
        config: BitmexExecutionClientConfig,
    ) -> anyhow::Result<Self> {
        config.validate_broadcaster_pool_sizes()?;

        if !config.has_api_credentials() {
            anyhow::bail!("BitMEX execution client requires API key and secret");
        }

        if let Some(account_id) = config.account_id {
            core.set_account_id(account_id);
        }

        let trader_id = core.trader_id;
        let account_id = core.account_id;
        let clock = get_atomic_clock_realtime();
        let emitter =
            ExecutionEventEmitter::new(clock, trader_id, account_id, AccountType::Margin, None);
        let api_key = config
            .api_key
            .as_ref()
            .map(|value| value.expose_secret().to_owned());
        let api_secret = config
            .api_secret
            .as_ref()

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Provide both api_key and api_secret in BitmexExecutionClientConfig
  2. Verify the env vars or secrets file backing the config are set in the runtime environment
  3. Validate the config (keys non-empty, correct key permissions for trading) before constructing the client

Example fix

// before
let config = BitmexExecutionClientConfig { api_key: None, api_secret: None, ... };
// after
let config = BitmexExecutionClientConfig {
    api_key: Some(std::env::var("BITMEX_API_KEY")?),
    api_secret: Some(std::env::var("BITMEX_API_SECRET")?),
    ...,
};
Defensive patterns

Strategy: validation

Validate before calling

// Python-style guard before building client
assert api_key and api_secret, "BitMEX execution client requires API key and secret"

Type guard

fn has_credentials(cfg: &BitmexExecutionClientConfig) -> bool {
    cfg.api_key.as_deref().map_or(false, |k| !k.is_empty())
        && cfg.api_secret.as_deref().map_or(false, |s| !s.is_empty())
}

Try / catch

let client = BitmexExecutionClient::new(core, config)
    .map_err(|e| { log::error!("exec client init: {e}"); ConfigError })?;

Prevention

When it happens

Trigger: Constructing BitmexExecutionClient::new() with a config where api_key or api_secret is None/empty (has_api_credentials() returns false).

Common situations: Missing or mistyped env vars/config fields for the API key and secret, live config accidentally built from the sandbox/testnet template with credentials stripped, or secrets not loaded from the secrets store.

Related errors


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