nautechsystems/nautilus_trader · error · anyhow::Error

{standard_secret_var} not found in config or environment

Error message

{standard_secret_var} not found in config or environment

What it means

resolve_credentials resolved the API key but not the secret: neither the config api_secret nor the standard environment variable named in the message (e.g. BINANCE_API_SECRET, BINANCE_TESTNET_API_SECRET, BINANCE_FUTURES_TESTNET_API_SECRET, BINANCE_DEMO_API_SECRET) is set. The adapter needs both halves of the credential pair to sign requests.

Source

Thrown at crates/adapters/binance/src/common/credential.rs:106

        };

    // Futures: soft deprecation (warn + fallback),
    // Spot/Margin: hard error on removed env vars.
    let is_futures = matches!(
        product_type,
        BinanceProductType::UsdM | BinanceProductType::CoinM
    );

    let api_key = config_api_key
        .or_else(|| std::env::var(standard_key_var).ok())
        .or_else(|| resolve_deprecated_var(deprecated_key_var, standard_key_var, is_futures))
        .ok_or_else(|| anyhow::anyhow!("{standard_key_var} not found in config or environment"))?;

    let api_secret = config_api_secret
        .or_else(|| std::env::var(standard_secret_var).ok())
        .or_else(|| resolve_deprecated_var(deprecated_secret_var, standard_secret_var, is_futures))
        .ok_or_else(|| {
            anyhow::anyhow!("{standard_secret_var} not found in config or environment")
        })?;

    Ok((api_key, api_secret))
}

fn resolve_deprecated_var(
    deprecated_var: &str,
    standard_var: &str,
    allow_fallback: bool,
) -> Option<String> {
    if deprecated_var.is_empty() {
        return None;
    }

    let value = std::env::var(deprecated_var).ok()?;

    if allow_fallback {
        log::warn!(

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Export the exact secret variable named in the message alongside the key
  2. Check the secret was not mangled by shell quoting/expansion (compare length against the value in the Binance console)
  3. Or pass api_secret directly in the client config instead of the environment
  4. Migrate deprecated *_ED25519_API_SECRET names to the standard names

Example fix

# before
export BINANCE_API_KEY=...   # secret missing

# after
export BINANCE_API_KEY=...
export BINANCE_API_SECRET=...
Defensive patterns

Strategy: validation

Validate before calling

let key = std::env::var("BINANCE_API_SECRET");
if key.is_err() {
    anyhow::bail!("BINANCE_API_SECRET missing - set it alongside the API key before starting the client");
}

Type guard

fn credentials_complete(env_vars: &[&str]) -> bool {
    env_vars.iter().all(|v| std::env::var(v).is_ok())
}

Try / catch

match resolve_credentials(config_key, config_secret, environment, product_type) {
    Ok((k, s)) => build_client(k, s),
    Err(e) if e.to_string().contains("API_SECRET") => { /* alert: half-configured credential */ Err(e) }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Config or environment supplies only the key (half-configured credential), or the secret env var name does not match the configured environment/product type while the key var does.

Common situations: Key exported but secret forgotten or truncated by shell quoting; secret stored in a secret manager that was not attached at deploy; mixed live/testnet variable names between key and secret; reliance on removed *_ED25519_* secret vars.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/a3736d74c16b3df1. Report an issue: GitHub.