nautechsystems/nautilus_trader · error
Cannot subscribe for synthetic instrument `InstrumentStatus`
Error message
Cannot subscribe for synthetic instrument `InstrumentStatus` data
What it means
InstrumentStatus data is venue-reported and has no meaning for synthetic instruments, which are generated locally. When a SubscribeCommand for InstrumentStatus targets a synthetic instrument ID, the engine bails immediately rather than forwarding an impossible command to a client.
Source
Thrown at crates/data/src/engine/mod.rs:1099
SubscribeCommand::Quotes(cmd) if cmd.instrument_id.is_synthetic() => {
self.subscribe_synthetic_quotes(cmd.instrument_id);
return Ok(());
}
SubscribeCommand::Quotes(cmd)
if self.is_spread_quote_command(cmd.instrument_id, cmd.params.as_ref()) =>
{
self.subscribe_spread_quotes(cmd);
return Ok(());
}
SubscribeCommand::Trades(cmd) if cmd.instrument_id.is_synthetic() => {
self.subscribe_synthetic_trades(cmd.instrument_id);
return Ok(());
}
SubscribeCommand::Instrument(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!("Cannot subscribe for synthetic instrument `Instrument` data");
}
SubscribeCommand::InstrumentStatus(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!("Cannot subscribe for synthetic instrument `InstrumentStatus` data");
}
SubscribeCommand::InstrumentClose(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!("Cannot subscribe for synthetic instrument `InstrumentClose` data");
}
SubscribeCommand::OptionGreeks(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!("Cannot subscribe for synthetic instrument `OptionGreeks` data");
}
_ => {} // Do nothing else
}
let retained = cmd.clone();
// Book ownership, including failed acquisitions, is already counted by the engine
let retain_on_failure = !matches!(
&cmd,
SubscribeCommand::BookDeltas(_) | SubscribeCommand::BookDepth10(_)
);
View on GitHub (pinned to 18893faf8b)
Solutions
- Exclude synthetic instrument IDs from InstrumentStatus subscriptions (skip ids where is_synthetic() is true).
- Subscribe to a supported synthetic stream (e.g. synthetic Trades) instead if generated data is needed.
- Only issue InstrumentStatus subscriptions for instruments that exist on a real venue.
Example fix
// before
engine.subscribe_instrument_status(synthetic_id)?;
// after
if !synthetic_id.is_synthetic() {
engine.subscribe_instrument_status(synthetic_id)?;
} Defensive patterns
Strategy: type-guard
Validate before calling
// Rust
if !instrument_id.is_synthetic() {
engine.subscribe_instrument_status(instrument_id)?;
} Type guard
// Rust
fn supports_instrument_status(id: &InstrumentId) -> bool {
!id.is_synthetic()
} Try / catch
// Rust
if let Err(e) = engine.subscribe_instrument_status(id) {
if e.to_string().contains("synthetic instrument `InstrumentStatus`") {
log::warn!("InstrumentStatus unavailable for synthetic {id}");
} else {
return Err(e.into());
}
} Prevention
- Never issue venue-derived data (status/close) subscriptions for synthetic IDs.
- Apply an is_synthetic() filter at the single helper that issues all subscriptions.
- Audit mixed instrument catalogs before bulk subscribing.
When it happens
Trigger: Subscribing to InstrumentStatus with an InstrumentId where is_synthetic() is true — e.g. blanket status subscriptions applied to all instrument IDs including synthetic ones.
Common situations: Generic subscription loops over a catalog that mixes real and synthetic instruments; strategy code copied from a real-instrument setup and retargeted at synthetic IDs.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot subscribe for synthetic instrument `Instrument` data
- Cannot subscribe for synthetic instrument `InstrumentClose`
- Cannot subscribe for synthetic instrument `OptionGreeks` dat
- Cannot unsubscribe from synthetic instrument `Instrument` da
- Cannot unsubscribe from synthetic instrument `InstrumentStat
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/10dd21506866e67e.
Report an issue: GitHub.