nautechsystems/nautilus_trader · error · anyhow::Error

Timed out connecting to IB Gateway/TWS after {}s

Error message

Timed out connecting to IB Gateway/TWS after {}s

What it means

The IB shared client wraps `ibapi::Client::connect` in a `tokio::time::timeout` using the configured `connect_timeout`. When the TCP/IB handshake does not complete in time, it raises this timeout error. Note the message interpolates `connection_timeout_secs` while the timeout uses `connect_timeout`, so verify both config values agree.

Source

Thrown at crates/adapters/interactive_brokers/src/common/shared_client.rs:171

            host,
            port,
            client_id,
            ref_count_val
        );
        return Ok(SharedClientHandle::new(client, registry, key));
    }

    let address = format!("{host}:{port}");
    let connect_timeout = Duration::from_secs(connection_timeout_secs);
    log::debug!(
        "No shared IB client found, establishing new connection to {} with timeout {:?}",
        address,
        connect_timeout
    );
    let client = tokio::time::timeout(connect_timeout, Client::connect(&address, client_id))
        .await
        .map_err(|_| {
            anyhow::anyhow!(
                "Timed out connecting to IB Gateway/TWS after {}s",
                connection_timeout_secs
            )
        })?
        .context("Failed to connect to IB Gateway/TWS")?;
    let client = Arc::new(client);

    {
        let mut guard = registry.lock();
        log::debug!(
            "Registering shared IB client in registry (host={}, port={}, client_id={})",
            host,
            port,
            client_id
        );
        guard.insert(key.clone(), (Arc::clone(&client), 1));
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Confirm IB Gateway/TWS is running and API access is enabled (Configure → API → Settings → Enable ActiveX and Socket Clients).
  2. Verify the configured `address` matches the Gateway API port (4001 live / 4002 paper for Gateway; 7496/7497 for TWS).
  3. Increase the connect timeout in your adapter config if Gateway is slow to start.
  4. Fix any variable mismatch so the message and the actual timeout use the same value (`connect_timeout` vs `connection_timeout_secs`).
  5. Check firewall/antivirus blocking the local port; test with `nc -vz 127.0.0.1 4002`.
Defensive patterns

Strategy: retry

Validate before calling

// Check reachability before connecting
assert!(std::net::TcpStream::connect(&address).is_ok(), "IB Gateway port unreachable: {address}");

Try / catch

match get_or_connect().await {
    Ok(c) => c,
    Err(e) if e.to_string().contains("Timed out connecting") => {
        tokio::time::sleep(Duration::from_secs(5)).await;
        get_or_connect().await? // bounded retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `get_or_connect` (on first use of the cached IB client) when IB Gateway/TWS is not running, is listening on a different host/port, or accepts the TCP connection but never completes the `Client::connect` handshake within `connect_timeout` seconds.

Common situations: Gateway not started or API connections disabled in Gateway settings; wrong `address` (host:port) in config (default 127.0.0.1:4001/7496 depending on live/paper); firewall blocking localhost port; Gateway API socket busy or stale client_id conflict; slow startup right after launching Gateway.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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