nautechsystems/nautilus_trader · error
Cannot unsubscribe from synthetic instrument `InstrumentClos
Error message
Cannot unsubscribe from synthetic instrument `InstrumentClose` data
What it means
The DataEngine refuses to process an UnsubscribeCommand for InstrumentClose data when the instrument_id is synthetic (e.g. IDs generated by SyntheticInstrument). Synthetic instruments are computed locally and their data streams are internal, so there is no client/provider subscription to tear down.
Source
Thrown at crates/data/src/engine/mod.rs:1279
if self.is_spread_quote_command(cmd.instrument_id, cmd.params.as_ref()) =>
{
self.unsubscribe_spread_quotes(cmd);
return Ok(());
}
UnsubscribeCommand::Trades(cmd) if cmd.instrument_id.is_synthetic() => {
self.unsubscribe_synthetic_trades(cmd.instrument_id);
return Ok(());
}
UnsubscribeCommand::Instrument(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!("Cannot unsubscribe from synthetic instrument `Instrument` data");
}
UnsubscribeCommand::InstrumentStatus(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!(
"Cannot unsubscribe from synthetic instrument `InstrumentStatus` data"
);
}
UnsubscribeCommand::InstrumentClose(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!(
"Cannot unsubscribe from synthetic instrument `InstrumentClose` data"
);
}
UnsubscribeCommand::OptionGreeks(cmd) if cmd.instrument_id.is_synthetic() => {
anyhow::bail!("Cannot unsubscribe from synthetic instrument `OptionGreeks` data");
}
_ => {}
}
if let Some(client) = self.get_command_client(cmd.client_id(), cmd.venue()) {
client.execute_unsubscribe(cmd);
} else {
log::error!(
"Cannot handle command: no client found for client_id={:?}, venue={:?}",
cmd.client_id(),
cmd.venue(),
);
}View on GitHub (pinned to 18893faf8b)
Solutions
- Do not call unsubscribe for InstrumentClose data on a synthetic instrument ID; synthetic data is managed internally
- Verify the instrument_id passed to unsubscribe is a real venue instrument (not one produced by SyntheticInstrument)
- Guard the call: check instrument_id.is_synthetic() before issuing the unsubscribe command
- If cleanup is needed, cancel the synthetic instrument subscription through the synthetic-instrument API instead
Example fix
// before
engine.unsubscribe(InstrumentClose::new(synthetic_instrument_id, client_id, venue));
// after
if !synthetic_instrument_id.is_synthetic() {
engine.unsubscribe(InstrumentClose::new(synthetic_instrument_id, client_id, venue));
} Defensive patterns
Strategy: validation
Validate before calling
if instrument_id.is_synthetic() {
// skip unsubscribe; synthetic data is engine-managed
return Ok(());
} Type guard
fn is_real_instrument(id: &InstrumentId) -> bool {
!id.is_synthetic()
} Try / catch
match engine.unsubscribe(cmd) {
Err(e) if e.to_string().contains("synthetic instrument") => log::warn!("skipped synthetic unsubscribe: {e}"),
Err(e) => return Err(e),
Ok(_) => {}
} Prevention
- Check is_synthetic() on every instrument ID before subscribe/unsubscribe commands
- Keep synthetic and real instrument subscription flows in separate code paths
- Log synthetic IDs distinctly so config mistakes surface early
When it happens
Trigger: Calling DataEngine.unsubscribe with an UnsubscribeCommand::InstrumentClose whose instrument_id.is_synthetic() is true, typically after subscribing to a synthetic instrument's close stream and then unsubscribing by that ID.
Common situations: Configuring a synthetic instrument ID (generated via SyntheticInstrument) where a real venue instrument ID is expected; reusing subscription code between synthetic and real instruments; stale subscription bookkeeping from a prior synthetic subscribe.
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 unsubscribe from synthetic instrument `Instrument` da
- Cannot unsubscribe from synthetic instrument `InstrumentStat
- Cannot subscribe for synthetic instrument `Instrument` data
- Cannot subscribe for synthetic instrument `InstrumentStatus`
- Cannot subscribe for synthetic instrument `InstrumentClose`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5fe166c096a1dd40.
Report an issue: GitHub.