nautechsystems/nautilus_trader · error
Spread instrument {symbol} not found
Error message
Spread instrument {symbol} not found What it means
Thrown by `request_spread_instrument` when OKX's spreads endpoint responds successfully but returns an empty list for the requested `sprd_id`. The adapter treats this as 'the spread instrument does not exist on OKX' and fails instrument loading for that symbol.
Source
Thrown at crates/adapters/okx/src/http/client.rs:2701
self.cache_instrument(instrument.clone());
Ok(instrument)
}
async fn request_spread_instrument(&self, symbol: &str) -> anyhow::Result<InstrumentAny> {
let resp = self
.inner
.get_spreads(GetSpreadsParams {
sprd_id: Some(symbol.to_string()),
..Default::default()
})
.await
.map_err(|e| anyhow::anyhow!(e))?;
let raw_spread = resp
.first()
.ok_or_else(|| anyhow::anyhow!("Spread instrument {symbol} not found"))?;
let ts_init = self.generate_ts_init();
parse_spread_instrument(raw_spread, None, None, None, None, ts_init)
.map_err(|e| OKXInstrumentDefinitionError::new(symbol, e).into())
}
/// Requests event contract series metadata from OKX.
///
/// # Errors
///
/// Returns an error if the HTTP request fails or the response cannot be deserialized.
pub async fn request_event_contract_series(
&self,
params: GetEventContractSeriesParams,
) -> Result<Vec<OKXEventContractSeries>, OKXHttpError> {
self.inner.get_event_contract_series(params).await
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the symbol matches an existing OKX sprd_id exactly (check OKX spread instruments endpoint or web UI).
- Remove or correct the spread instrument in your adapter/venue configuration.
- Check whether the spread was delisted and pick an active equivalent.
- If the symbol is user-defined (custom spread), load it as a locally defined instrument instead of fetching from OKX.
Example fix
// before
let instrument_id = InstrumentId::from_str("OKX-SPREAD/BTC-USDT_BTC-USDT-TYPO")?;
// after
let instrument_id = InstrumentId::from_str("OKX-SPREAD/BTC-USDT_BTC-USDT-240329")?; Defensive patterns
Strategy: validation
Validate before calling
// Before loading, verify the spread exists on OKX
let exists = http.get_spreads(GetSpreadsParams { sprd_id: Some(symbol.into()), ..Default::default() }).await?.len() > 0;
anyhow::ensure!(exists, "unknown OKX spread: {symbol}"); Try / catch
match client.load_instrument(&spread_id).await {
Ok(inst) => Ok(Some(inst)),
Err(e) if e.to_string().contains("not found") => { log::warn!("skipping unknown spread {spread_id}"); Ok(None) }
Err(e) => Err(e),
}; Prevention
- Copy spread IDs exactly from OKX (sprd_id format) rather than typing them by hand.
- Validate all configured instruments at startup and fail fast with a clear list of unknown symbols.
- Periodically refresh instrument lists; remove delisted spreads from config.
- Keep OKX instrument catalog dumps alongside config for cross-checking.
When it happens
Trigger: Requesting an instrument for a spread symbol that OKX does not list (typo in symbol, delisted spread, or a synthetic/invented spread ID not registered on OKX).
Common situations: Config referencing a spread instrument ID that was delisted; symbol formatted incorrectly (must match OKX's sprd_id exactly, e.g. BTC-USDT_BTC-USDT-240329); querying before the spread's listing date.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- `tick_sz` is empty for {}
- `lot_sz` is empty for {}
- Empty underlying for {inst_id}: instrument may be pre-open o
- No instruments loaded for configured types {instrument_types
- Instrument {instrument_id} not found in cache
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f97d93d9c3d3168a.
Report an issue: GitHub.