nautechsystems/nautilus_trader · error

`api_key`, `api_secret`, `api_passphrase` credentials must b

Error message

`api_key`, `api_secret`, `api_passphrase` credentials must be provided together

What it means

OKX WebSocket client construction validates that credentials are all-or-nothing: `api_key`, `api_secret`, and `api_passphrase` must each be supplied or all omitted. A partial set (e.g. key without passphrase) cannot authenticate with OKX, so `new` returns this error instead of building a client that would fail later.

Source

Thrown at crates/adapters/okx/src/websocket/client.rs:340

    #[allow(clippy::too_many_arguments)]
    pub fn new(
        url: Option<String>,
        api_key: Option<String>,
        api_secret: Option<String>,
        api_passphrase: Option<String>,
        _account_id: Option<AccountId>,
        heartbeat: Option<u64>,
        auth_timeout_secs: Option<u64>,
        transport_backend: TransportBackend,
        proxy_url: Option<String>,
    ) -> anyhow::Result<Self> {
        let url = url.unwrap_or(OKX_WS_PUBLIC_URL.to_string());
        let credential = match (api_key, api_secret, api_passphrase) {
            (Some(key), Some(secret), Some(passphrase)) => {
                Some(Credential::new(key, secret, passphrase))
            }
            (None, None, None) => None,
            _ => anyhow::bail!(
                "`api_key`, `api_secret`, `api_passphrase` credentials must be provided together"
            ),
        };

        let signal = Arc::new(AtomicBool::new(false));
        let subscriptions_inst_type = Arc::new(DashMap::new());
        let subscriptions_inst_family = Arc::new(DashMap::new());
        let subscriptions_inst_id = Arc::new(DashMap::new());
        let subscriptions_bare = Arc::new(DashMap::new());
        let subscriptions_state = SubscriptionState::new(OKX_WS_TOPIC_DELIMITER);

        Ok(Self {
            clock: get_atomic_clock_realtime(),
            url,
            vip_level: Arc::new(AtomicU8::new(0)),
            credential,
            heartbeat,
            auth_timeout_secs: auth_timeout_secs.unwrap_or(AUTHENTICATION_TIMEOUT_SECS),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Provide all three: `api_key`, `api_secret`, and `api_passphrase` together.
  2. Or provide none of them to create a public (unauthenticated) client.
  3. Check your config/env for a missing `api_passphrase` — OKX credentials require it and it is the most commonly omitted piece.

Example fix

// before
OKXWebSocketClient::new(Some(api_key), None, None, None, None, url).await?;
// after
OKXWebSocketClient::new(Some(api_key), Some(api_secret), Some(api_passphrase), None, None, url).await?;
Defensive patterns

Strategy: validation

Validate before calling

let creds = [api_key.is_some(), api_secret.is_some(), api_passphrase.is_some()];
if creds.iter().any(|&x| x) && !creds.iter().all(|&x| x) {
    return Err(anyhow::anyhow!("api_key, api_secret, api_passphrase must be set together"));
}

Prevention

When it happens

Trigger: Calling `OKXWebSocketClient::new`/`connect`-facing constructor with exactly one or two of the three credential strings set to `Some`.

Common situations: Config files or env vars defining only some of `api_key`/`api_secret`/`api_passphrase` (commonly the passphrase is forgotten for OKX); copy-pasting public-client setup while leaving one credential set.

Related errors


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