nautechsystems/nautilus_trader · error

Missing environment variable

Error message

Missing environment variable: {secret_env}

What it means

with_credentials resolves the API secret from the provided value or from the environment-specific secret variable (e.g. DERIBIT_TESTNET_API_SECRET). When both the explicit api_secret argument and the environment variable are absent, authenticated construction fails. The API key may be present, but the client cannot authenticate without the secret.

Solutions

  1. Export the required secret variable (e.g. `export DERIBIT_API_SECRET=...`) before process start.
  2. Pass the api_secret explicitly as the second argument to with_credentials.
  3. Verify both key and secret environment variables match the configured environment (testnet vs mainnet).

Example fix

// before
let client = DeribitWebSocketClient::with_credentials(Some(key), None, None, environment, ...).await?;
// after
let secret = std::env::var("DERIBIT_API_SECRET")?; // or pass Some(secret)
let client = DeribitWebSocketClient::with_credentials(Some(key), Some(secret), None, environment, ...).await?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust: ensure both key and secret are set before connecting
std::env::var("DERIBIT_API_SECRET")
    .map_err(|_| anyhow!("set DERIBIT_API_SECRET (or pass api_secret) before connecting"))?;

Type guard

fn secret_env_present(environment: Environment) -> bool {
    let (_, secret_env) = credential_env_vars(environment);
    std::env::var(secret_env).is_ok()
}

Try / catch

let client = match DeribitWebSocketClient::with_credentials(Some(key), None, None, env, ...).await {
    Ok(c) => c,
    Err(e) if e.to_string().contains("Missing environment variable") => {
        return Err(anyhow!("configure {}", e))
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling with_credentials with a key supplied (or key env var set) but no api_secret argument and the secret env var unset in the process environment.

Common situations: Setting only DERIBIT_API_KEY but forgetting DERIBIT_API_SECRET, .env files loaded after client construction, secrets not mounted in containers, or testnet secret variable used while environment is production (or vice versa).

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/deribit/src/websocket/client.rs:312

    /// - Mainnet: `DERIBIT_API_KEY` and `DERIBIT_API_SECRET`
    ///
    /// # Errors
    ///
    /// Returns an error if neither the argument nor the environment variable
    /// provides a credential.
    pub fn with_credentials(
        environment: DeribitEnvironment,
        api_key: Option<String>,
        api_secret: Option<String>,
        auth_timeout_secs: Option<u64>,
        proxy_url: Option<String>,
    ) -> anyhow::Result<Self> {
        let (key_env, secret_env) = credential_env_vars(environment);

        let api_key = get_or_env_var_opt(api_key, key_env)
            .ok_or_else(|| anyhow::anyhow!("Missing environment variable: {key_env}"))?;
        let api_secret = get_or_env_var_opt(api_secret, secret_env)
            .ok_or_else(|| anyhow::anyhow!("Missing environment variable: {secret_env}"))?;

        Self::new(
            None,
            Some(api_key),
            Some(api_secret),
            DERIBIT_WS_HEARTBEAT_SECS,
            auth_timeout_secs,
            environment,
            TransportBackend::default(),
            proxy_url,
        )
    }

    /// Returns the current connection mode.
    fn connection_mode(&self) -> ConnectionMode {
        let mode_u8 = self.connection_mode.load().load(Ordering::Relaxed);
        ConnectionMode::from_u8(mode_u8)
    }

View on GitHub (pinned to 18893faf8b)