nautechsystems/nautilus_trader · error
{e}
Error message
{e} What it means
`request_instruments` fetches the full instrument list from the AX REST API via `get_instruments()`; a failed HTTP call is converted with `anyhow::anyhow!(e)` and propagated with no extra context (message is just the inner error). Conversion/parse of the returned instruments happens afterwards, so this error is specifically the fetch step failing.
Source
Thrown at crates/adapters/architect_ax/src/http/client.rs:1421
/// Requests all instruments from Ax.
///
/// Fee rates fall back to the rates last resolved from `GET /whoami`, and to zero when no
/// rates have been resolved.
///
/// # Errors
///
/// Returns an error if the HTTP request fails or instrument parsing fails.
pub async fn request_instruments(
&self,
maker_fee: Option<Decimal>,
taker_fee: Option<Decimal>,
) -> anyhow::Result<Vec<InstrumentAny>> {
let resp = self
.inner
.get_instruments()
.await
.map_err(|e| anyhow::anyhow!(e))?;
let (maker_fee, taker_fee) = self.resolve_fees(maker_fee, taker_fee);
let ts_init = self.generate_ts_init();
let mut instruments: Vec<InstrumentAny> = Vec::new();
for inst in &resp.instruments {
if inst.state == AxInstrumentState::Delisted {
log::debug!("Skipping delisted instrument: {}", inst.symbol);
continue;
}
// Skip test instruments (not real tradable products)
if inst.symbol.starts_with("TEST") {
log::debug!("Skipping test instrument: {}", inst.symbol);
continue;
}
match parse_instrument(inst, maker_fee, taker_fee, ts_init, ts_init) {View on GitHub (pinned to 18893faf8b)
Solutions
- Read the propagated error text for the HTTP status or transport message.
- Retry with increased `max_retries` / `retry_delay_max_ms` if rate-limited or transient.
- Verify the configured `http_base_url` and network/proxy path to AX.
- Check AX service status if 5xx errors persist.
Defensive patterns
Strategy: retry
Validate before calling
// before requesting instruments
assert!(ax_config.max_retries > 0, "enable retries for instrument loads");
// network preflight
let resp = reqwest::get(format!("{base}/instruments")).await?;
assert!(resp.status().is_success(), "instruments endpoint returned {}", resp.status()); Try / catch
match client.request_instruments(None, None).await {
Ok(instruments) => instruments,
Err(e) if is_transient(&e.to_string()) => {
tokio::time::sleep(Duration::from_secs(5)).await;
client.request_instruments(None, None).await?
}
Err(e) => return Err(e),
} Prevention
- Enable client-level retries with backoff for instrument loads.
- Avoid loading all instruments during API maintenance windows.
- Respect rate limits; stagger multi-venue startup.
- Monitor and log HTTP statuses from the AX API.
When it happens
Trigger: Calling `request_instruments` (instrument provider load) when the instruments REST endpoint errors: network failure, timeout, HTTP 4xx/5xx, malformed response rejected by the HTTP layer.
Common situations: AX API outage or maintenance; rate limiting during mass instrument loads; wrong base URL; firewall/proxy blocking the request.
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
- failed to request AX whoami: {e}
- Failed to resolve AX instrument {symbol} via GET /instrument
- {e}
- Failed to get dataset range: {e}
- Failed to get range: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/da4d3bd554827b04.
Report an issue: GitHub.