nautechsystems/nautilus_trader · error · anyhow::Error
Gateway `{}` not ready after {} seconds
Error message
Gateway `{}` not ready after {} seconds What it means
DockerizedIBGateway::start polls the container once per second (for up to the configured timeout or an explicit wait value) checking whether the gateway reports logged-in status. If the gateway never becomes ready within that window, start bails with the container name and elapsed seconds.
Source
Thrown at crates/adapters/interactive_brokers/src/gateway/dockerized.rs:460
let wait_time = wait.unwrap_or(self.config.timeout);
let mut waited = 0u64;
while waited < wait_time {
if self.is_logged_in(&container_id).await.unwrap_or(false) {
tracing::debug!(
"Gateway `{}` ready. VNC port is {:?}",
self.container_name,
self.config.vnc_port
);
return Ok(());
}
tracing::debug!("Waiting for IB Gateway to start");
tokio::time::sleep(Duration::from_secs(1)).await;
waited += 1;
}
anyhow::bail!(
"Gateway `{}` not ready after {} seconds",
self.container_name,
wait_time
)
}
/// Safely start the gateway, handling container already exists errors.
///
/// # Arguments
///
/// * `wait` - Optional wait time in seconds
///
/// # Errors
///
/// Returns an error if startup fails (other than container exists).
pub async fn safe_start(&mut self, wait: Option<u64>) -> anyhow::Result<()> {
match self.start(wait).await {
Ok(()) => Ok(()),View on GitHub (pinned to 18893faf8b)
Solutions
- Confirm the 2FA/I.login prompt was accepted in the IB Gateway UI or mobile app (check via the container's VNC port) Increase DockerizedIBGatewayConfig.timeout (or pass a larger wait to start) and retry Check container logs: docker logs <container_name> for credential/config errors Verify the gateway image and paper/live trading mode match your credentials
Example fix
// before
let config = DockerizedIBGatewayConfig { timeout: 60, .. };
// after
let config = DockerizedIBGatewayConfig { timeout: 300, .. }; // allow time for 2FA Defensive patterns
Strategy: retry
Validate before calling
// before starting, ensure Docker is up and image is present // docker info && docker image inspect <gateway_image>
Try / catch
loop {
match gateway.start(Some(300)).await {
Ok(()) => break,
Err(e) if e.to_string().contains("not ready after") => {
warn!("gateway not ready: {e}; retrying with longer timeout");
tokio::time::sleep(Duration::from_secs(10)).await;
}
Err(e) => return Err(e),
}
} Prevention
- Approve IB 2FA prompts promptly when starting the gateway
- Set a generous timeout (5+ minutes) for cold starts and image pulls
- Monitor container logs and health before assuming timeout means failure
- Verify paper/live credentials match the configured trading mode
When it happens
Trigger: start() -> is_logged_in() keeps returning false until waited >= wait_time (config timeout or the wait argument). Commonly because IB credentials/2FA were not approved, the gateway image is slow to pull/start, or the container is crash-looping.
Common situations: First-time 2FA notification not confirmed in IB's mobile app; wrong trading mode (paper vs live) credentials; slow machine or cold Docker daemon exceeding the default timeout; gateway container restarting due to bad config.
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
- Timeout must be less than 3600 seconds
- Gateway feature is not enabled. Build with --features gatewa
- Timed out connecting to IB Gateway/TWS after {}s
- username not set nor available in env TWS_USERNAME
- password not set nor available in env TWS_PASSWORD
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3bbfe132407a953e.
Report an issue: GitHub.