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
- Confirm IB Gateway/TWS is running and API access is enabled (Configure → API → Settings → Enable ActiveX and Socket Clients).
- Verify the configured `address` matches the Gateway API port (4001 live / 4002 paper for Gateway; 7496/7497 for TWS).
- Increase the connect timeout in your adapter config if Gateway is slow to start.
- Fix any variable mismatch so the message and the actual timeout use the same value (`connect_timeout` vs `connection_timeout_secs`).
- 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
- Start IB Gateway before the adapter and wait for its API port to listen.
- Confirm host/port config (4001/4002 Gateway, 7496/7497 TWS) and enable API connections in Gateway settings.
- Set a connect timeout with headroom for Gateway startup.
- Ensure client_id uniqueness to avoid handshake contention.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Failed to connect after {max_attempts} attempts
- Failed to connect to Databento LSG: {e}
- subscription confirmation failed: {e}
- Timeout waiting for account {account_id} to be registered af
- Timeout must be less than 3600 seconds
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fc036e665182cb99.
Report an issue: GitHub.