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
- Inspect the chained source error for the HTTP status/transport cause.
- Verify API key/secret are valid and have account read permissions.
- Confirm `http_base_url` points at the correct AX environment.
- Check network/proxy connectivity to the AX API (curl the whoami endpoint manually).
- 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
- Validate API key/secret and their permissions before starting the client.
- Configure max_retries/retry_delay_max_ms for transient failures.
- Monitor AX API status and alert on 4xx/5xx bursts.
- Confirm the base URL matches the intended environment (prod vs test).
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
- {e}
- {e}
- No result in ticker response
- No result in book summary response
- No result in expirations response
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/eea627358042d8fd.
Report an issue: GitHub.