nautechsystems/nautilus_trader · error · anyhow::Error
Failed to resolve AX instrument {symbol} via GET /instrument
Error message
Failed to resolve AX instrument {symbol} via GET /instrument: {e} What it means
request_fill_reports resolves each fill's symbol by cache lookup, then a live GET /instrument; this error wraps the failure of that fetch. It means the fill's symbol was not in the instrument cache and the HTTP call failed — network/5xx, auth/scopes, a 404 for a delisted or unknown symbol, or the returned definition failing to parse.
Source
Thrown at crates/adapters/architect_ax/src/http/client.rs:2383
Err(e) => {
log::warn!("Failed to parse position for {}: {e}", position.symbol);
}
}
}
Ok(reports)
}
async fn resolve_report_instrument(&self, symbol: Ustr) -> anyhow::Result<InstrumentAny> {
if let Some(instrument) = self.get_instrument(&symbol) {
return Ok(instrument);
}
let instrument = self
.request_instrument(symbol, None, None)
.await
.map_err(|e| {
anyhow::anyhow!("Failed to resolve AX instrument {symbol} via GET /instrument: {e}")
})?;
self.cache_instrument(instrument.clone());
Ok(instrument)
}
/// Cancels all open orders for an instrument.
///
/// # Errors
///
/// Returns an error if the request fails.
pub async fn cancel_all_orders(&self, instrument_id: InstrumentId) -> Result<(), AxHttpError> {
let request = CancelAllOrdersRequest::new().with_symbol(instrument_id.symbol.inner());
self.inner.cancel_all_orders(&request).await?;
Ok(())
}
}
View on GitHub (pinned to a4b06ed870)
Solutions
- Warm the instrument cache first: call the adapter's instrument loading (request_instruments / subscribe instruments) before requesting fills
- Look the symbol up in the AX web UI — delisted or renamed symbols 404 and need manual handling
- Verify API credentials, scopes, and network path to the /instrument endpoint
- Retry once for transient 5xx/network errors before treating it as a data problem
Example fix
// before — fills first, cache cold let reports = client.request_fill_reports(account_id, start, end).await?; // after — instruments first, then fills client.request_instruments(None).await?; let reports = client.request_fill_reports(account_id, start, end).await?;
Defensive patterns
Strategy: retry
Validate before calling
// Warm the instrument cache before requesting fills so /instrument is rarely hit let instruments = client.request_instruments(None).await?; let known: HashSet<Ustr> = instruments.iter().map(|i| i.id().symbol.inner()).collect(); // pre-check the fills window's symbols if you already know them; otherwise this at least // populates the cache that resolve_report_instrument consults first
Try / catch
match client.request_fill_reports(account_id, start, end).await {
Ok(reports) => Ok(reports),
Err(e) if e.to_string().contains("Failed to resolve AX instrument") => {
log::warn!("instrument fetch failed (network/scope/delisted?): {e}");
tokio::time::sleep(Duration::from_secs(2)).await;
// one retry covers transient 5xx; persistent failure means bad symbol or credentials
client.request_fill_reports(account_id, start, end).await
}
Err(e) => Err(e),
} Prevention
- Load instruments at adapter startup, before any fills or order reconciliation
- Reconcile fills for delisted symbols manually — they 404 on /instrument and will always fail
- Monitor credential expiry and scopes: instrument reads are the first calls to fail on auth problems
When it happens
Trigger: A fill arrives for a symbol the adapter never loaded (fresh client doing fills reconciliation before instrument loading); the API token lacks instrument-read scope; the symbol was delisted between execution and reconciliation; transient connectivity blip or 5xx on /instrument.
Common situations: Cold-starting the AX adapter and immediately requesting fill reports; reconciling historical fills for delisted contracts; testnet symbols not present on the prod endpoint; expired or rotated API credentials.
Related errors
- AX fills total_count must be non-negative, was {total_count}
- AX fills total_count changed during pagination: expected {ex
- AX fills pagination returned duplicate trade ID {}
- AX fills pagination returned more unique rows ({}) than tota
- AX fills returned an empty next_cursor
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/4bbe5aa659ac2300.
Report an issue: GitHub.