nautechsystems/nautilus_trader · error · anyhow::Error

Interactive Brokers execution client_id must not be a multip

Error message

Interactive Brokers execution client_id must not be a multiple of 1000 because order ID partitioning uses client_id % 1000; got {}

What it means

The InteractiveBrokersExecutionClient constructor enforces that the configured execution client_id is not a multiple of 1000, because the adapter partitions order IDs using client_id % 1000 and a multiple of 1000 would collide with other clients' ID ranges. The ensure! fails fast at client construction with this message including the offending client_id.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/core.rs:257

impl InteractiveBrokersExecutionClient {
    /// Creates a new [`InteractiveBrokersExecutionClient`].
    ///
    /// # Arguments
    ///
    /// * `core` - Core execution client functionality
    /// * `config` - Configuration for the client
    /// * `instrument_provider` - Instrument provider
    ///
    /// # Errors
    ///
    /// Returns an error if client creation fails.
    pub fn new(
        mut core: ExecutionClientCore,
        config: InteractiveBrokersExecutionClientConfig,
        instrument_provider: Arc<InteractiveBrokersInstrumentProvider>,
    ) -> anyhow::Result<Self> {
        anyhow::ensure!(
            !config.client_id.unsigned_abs().is_multiple_of(1000),
            "Interactive Brokers execution client_id must not be a multiple of 1000 because order ID partitioning uses client_id % 1000; got {}",
            config.client_id
        );

        // If account_id is provided in config, use it
        if let Some(account_id) = &config.account_id {
            core.account_id = AccountId::from(account_id.clone());
        }

        let pending_tasks = TaskGroup::new();
        let session_tasks = TaskGroup::new();

        Ok(Self {
            core,
            config,
            instrument_provider,
            is_connected: AtomicBool::new(false),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change client_id in the InteractiveBrokers execution client config to a non-multiple of 1000 (e.g. 1–999 modulo 1000, like 5 or 1001).
  2. If multiple clients run against one gateway, assign each a distinct client_id that is not a multiple of 1000 to avoid ID partition overlap.
  3. Check for generated or templated configs that compute client_id and ensure the generator avoids round multiples of 1000.

Example fix

// before
[execution]
client_id = 1000
// after
[execution]
client_id = 1001
Defensive patterns

Strategy: validation

Validate before calling

fn client_id_is_valid(client_id: i64) -> bool {
    client_id.unsigned_abs() % 1000 != 0
}

Prevention

When it happens

Trigger: Constructing the execution client with an InteractiveBrokersExecutionClientConfig whose client_id is 0, 1000, 2000, 7000, etc. — i.e. any unsigned value where client_id % 1000 == 0.

Common situations: Config defaults or copied example configs using client_id values like 0 or 1000; multiple gateway sessions where a user picked a round-number client ID; automations that derive client IDs by multiplying or scaling other numbers.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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