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

  1. Read the propagated error text for the HTTP status or transport message.
  2. Retry with increased `max_retries` / `retry_delay_max_ms` if rate-limited or transient.
  3. Verify the configured `http_base_url` and network/proxy path to AX.
  4. 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

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


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