nautechsystems/nautilus_trader · error · Error::Io(std::io::Error)

reconnection timed out after {}s

Error message

reconnection timed out after {}s

What it means

The library spawns a reconnection future (using the configured connector and mode) inside a timeout, and the future did not complete within `connect_timeout` seconds. The result is a `ErrorKind::TimedOut` Io error, meaning the remote endpoint did not accept the new connection in time.

Source

Thrown at crates/network/src/socket/client.rs:389

        log::info!("Reconnecting");

        if ConnectionMode::from_atomic(&self.connection_mode).is_disconnect() {
            log::debug!("Reconnect aborted due to disconnect state");
            return Ok(ReconnectOutcome::Aborted);
        }

        // Bound only connection establishment; the swap below must run to completion
        let (reader, new_writer) = dst::time::timeout(
            self.connect_timeout,
            Self::tls_connect_with_server(
                &self.config.url,
                self.config.mode,
                self.connector.clone(),
            ),
        )
        .await
        .map_err(|_| {
            Error::Io(std::io::Error::new(
                std::io::ErrorKind::TimedOut,
                format!(
                    "reconnection timed out after {}s",
                    self.connect_timeout.as_secs_f64()
                ),
            ))
        })??;

        if ConnectionMode::from_atomic(&self.connection_mode).is_disconnect() {
            log::debug!("Reconnect aborted mid-flight (after connect)");
            return Ok(ReconnectOutcome::Aborted);
        }
        log::debug!("Connected");

        // Use a oneshot channel to synchronize with the writer task.
        // We must verify that the buffer was successfully drained before transitioning to ACTIVE
        // to prevent silent message loss if the new connection drops immediately.
        let (tx, rx) = tokio::sync::oneshot::channel();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the remote host:port is reachable (`ping`, `nc -vz host port`) and the server is up.
  2. Increase `connect_timeout` in the client config to a realistic value (e.g. 10–30s).
  3. Check for firewall/VPN/proxy rules blocking outbound connections to the endpoint.
  4. Retry reconnection with backoff; transient outages often resolve.

Example fix

// before
config.connect_timeout = Duration::from_millis(500);
// after
config.connect_timeout = Duration::from_secs(15);
Defensive patterns

Strategy: retry

Validate before calling

// pre-check endpoint reachability before reconnecting
assert!(std::net::TcpStream::connect_timeout(
    &addr, Duration::from_secs(3)).is_ok(), "endpoint unreachable");

Try / catch

match client.reconnect().await {
    Err(e) if e.kind() == std::io::ErrorKind::TimedOut => {
        tokio::time::sleep(backoff.next()).await;
        // retry reconnect
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling reconnect logic (automatically on connection loss or via explicit reconnect) while the remote server is down, unreachable, dropping SYN packets, or when `connect_timeout` is set too aggressively for a slow network.

Common situations: Exchange/data-feed endpoints behind firewalls that silently drop traffic, DNS or routing problems, server restarts longer than the configured timeout, or misconfigured timeouts of a few hundred milliseconds.

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/1f6d91c77f389792. Report an issue: GitHub.