nautechsystems/nautilus_trader · error · anyhow::Error
Subscription error: {e:?}
Error message
Subscription error: {e:?} What it means
While setting up a tick-by-tick quote subscription, the adapter awaits an acknowledgment from the IB stream; if the subscription future yields an Err (e.g. farm not connected, rejected subscription), the error is logged and propagated with the Debug form of the source error.
Source
Thrown at crates/adapters/interactive_brokers/src/data/core_streams.rs:1088
e
);
if !wait_for_data_farm_recovery_or_cancel(
&data_farm_state,
farm_generation,
&cancellation_token,
)
.await
{
subscription.cancel().await;
return Ok(());
}
farm_generation = data_farm_state.recovery_generation();
break;
}
Some(Err(e)) => {
tracing::error!("Subscription error for {}: {:?}", instrument_id, e);
anyhow::bail!("Subscription error: {e:?}");
}
None => break,
}
}
}
}
}
Ok(())
}
#[allow(clippy::too_many_arguments)]
pub(super) async fn handle_trade_subscription(
client: Arc<ibapi::Client>,
contract: ibapi::contracts::Contract,
instrument_id: InstrumentId,
price_precision: u8,
size_precision: u8,View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the IB Gateway/TWS connection is live and the market data farm is connected before subscribing
- Retry the subscription (recovery generation handling suggests transient farm issues)
- Confirm market data subscriptions/permissions cover the instrument's exchange
- Check the inner error (logged as 'Subscription error for {instrument_id}') for the root cause
Example fix
// before
client.subscribe_quotes(instrument_id).await?;
// after
match client.subscribe_quotes(instrument_id).await {
Ok(stream) => ..., // use stream
Err(e) => {
tracing::warn!("quote subscription failed for {instrument_id}: {e:?}; retrying after reconnect");
client.reconnect().await?;
client.subscribe_quotes(instrument_id).await?;
}
} Defensive patterns
Strategy: retry
Try / catch
match client.subscribe_quotes(instrument_id).await {
Ok(handle) => handle,
Err(e) if e.to_string().contains("Subscription error") => {
tracing::warn!("transient subscription failure for {instrument_id}; retrying after backoff");
tokio::time::sleep(Duration::from_secs(2)).await;
client.subscribe_quotes(instrument_id).await?
}
Err(e) => return Err(e),
} Prevention
- Confirm gateway connectivity and market data farm status before subscribing
- Verify market data permissions for the instrument's exchange
- Use tick-by-tick subscriptions only for supported instrument types
- Monitor the inner error logged as 'Subscription error for {instrument_id}' for root cause
When it happens
Trigger: Calling subscribe_quotes when the data farm is down/recovering, the instrument is not subscribed on the gateway, or the internal subscription channel returned an error — observed as Some(Err(e)) on the ack channel.
Common situations: IB Gateway/TWS disconnects mid-subscription, market data farm drops during recovery, requesting tick-by-tick data for unsupported instruments, or market-data permissions missing.
Related errors
- Unknown IB historical tick type: {value}
- Binance liquidation custom data requires BINANCE venue instr
- Binance Futures supports L1_MBP and L2_MBP order book subscr
- Binance Spot supports L1_MBP and L2_MBP order book subscript
- Instrument {instrument_id} not found and `auto_load_missing_
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3608eac2923a72ae.
Report an issue: GitHub.