nautechsystems/nautilus_trader · error

failed to request AX whoami: {e}

Error message

failed to request AX whoami: {e}

What it means

`AxHttpClient::request_account_fees` first calls the AX `whoami` endpoint to discover the account from which fee tiers are resolved; if `get_whoami()` fails (HTTP error, auth rejection, network failure), the error is wrapped with context "failed to request AX whoami". This is the pre-flight account lookup for maker/taker fee resolution.

Source

Thrown at crates/adapters/architect_ax/src/http/client.rs:1379

    ///
    /// AX reports fee rates per account rather than per user, and returns the accounts the
    /// credentials can act on. The first entry is used, which is the account AX resolves when a
    /// request carries no explicit selector. The rates are retained so later instrument requests,
    /// including the periodic refresh, keep reporting them.
    ///
    /// Requires an authenticated client.
    ///
    /// # Errors
    ///
    /// Returns an error if the request fails, the response carries no accounts, or the selected
    /// account supplies no fee rates. An absent rate is not treated as zero, because a zero rate
    /// is itself valid and a silent zero would outlive the response that caused it.
    pub async fn request_account_fees(&self) -> anyhow::Result<(Decimal, Decimal)> {
        let whoami = self
            .inner
            .get_whoami()
            .await
            .map_err(|e| anyhow::anyhow!(e))
            .context("failed to request AX whoami")?;

        let Some(account) = whoami.accounts.first() else {
            anyhow::bail!("AX whoami returned no accounts to resolve fees from");
        };

        if whoami.accounts.len() > 1 {
            log::warn!(
                "AX credentials cover {} accounts, using fee rates from {}",
                whoami.accounts.len(),
                account.id,
            );
        }

        let (Some(maker_fee), Some(taker_fee)) = (account.maker_fee, account.taker_fee) else {
            anyhow::bail!("AX whoami account {} supplied no fee rates", account.id);
        };

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the chained source error for the HTTP status/transport cause.
  2. Verify API key/secret are valid and have account read permissions.
  3. Confirm `http_base_url` points at the correct AX environment.
  4. Check network/proxy connectivity to the AX API (curl the whoami endpoint manually).
  5. Retry if the cause was transient (5xx/timeout) — the client has retry settings that can be raised.

Example fix

// diagnose
match client.request_account_fees().await {
    Ok((maker, taker)) => println!("fees: {maker} {taker}"),
    Err(e) => {
        // anyhow chain shows "failed to request AX whoami: <cause>"
        eprintln!("{e:#}");
        // fix keys/URL, then retry
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// before connect: sanity-check credentials and endpoint reachability
let key = std::env::var("AX_API_KEY")?;
let secret = std::env::var("AX_API_SECRET")?;
assert!(!key.is_empty() && !secret.is_empty());
// optionally ping the REST base URL before full connect
let status = reqwest::get(format!("{base}/health")).await?.status();
assert!(status.is_success(), "AX API unreachable: {status}");

Try / catch

for attempt in 0..3 {
    match client.request_account_fees().await {
        Ok((m, t)) => break (m, t),
        Err(e) if e.root_cause().to_string().contains("whoami") && attempt < 2 => {
            tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
        }
        Err(e) => return Err(e.context("whoami failed after retries; check AX_API_KEY/AX_API_SECRET")),
    }
}

Prevention

When it happens

Trigger: Calling `request_account_fees` (during client connect/instrument load) when the whoami REST call fails: invalid or expired API key/secret, network/DNS failure, AX API returning 4xx/5xx, or base URL misconfiguration.

Common situations: Wrong or rotated API keys; keys lacking account-scoped permissions; AX API downtime; pointing the client at the wrong environment URL so the endpoint 404s.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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