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

  1. Verify the IB Gateway/TWS connection is live and the market data farm is connected before subscribing
  2. Retry the subscription (recovery generation handling suggests transient farm issues)
  3. Confirm market data subscriptions/permissions cover the instrument's exchange
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/3608eac2923a72ae. Report an issue: GitHub.