shadowsocks/shadowsocks-rust · error

connect {} timeout

Error message

connect {} timeout

What it means

When establishing the TCP connection to a shadowsocks server, the connect is wrapped in a timeout (from the server's connect_timeout option). If the underlying TCP connect neither succeeds nor fails before the deadline, the library aborts with ErrorKind::TimedOut and "connect <addr> timeout". This is a transport-level timeout, not an authentication or protocol failure.

Source

Thrown at crates/shadowsocks/src/relay/tcprelay/proxy_stream/client.rs:124

        opts: &ConnectOpts,
        map_fn: F,
    ) -> io::Result<Self>
    where
        A: Into<Address>,
        F: FnOnce(OutboundTcpStream) -> S,
    {
        let stream = match svr_cfg.timeout() {
            Some(d) => {
                match time::timeout(
                    d,
                    OutboundTcpStream::connect_server_with_opts(&context, svr_cfg.tcp_external_addr(), opts),
                )
                .await
                {
                    Ok(Ok(s)) => s,
                    Ok(Err(e)) => return Err(e),
                    Err(..) => {
                        return Err(io::Error::new(
                            ErrorKind::TimedOut,
                            format!("connect {} timeout", svr_cfg.addr()),
                        ));
                    }
                }
            }
            None => OutboundTcpStream::connect_server_with_opts(&context, svr_cfg.tcp_external_addr(), opts).await?,
        };

        trace!(
            "connected tcp remote {} (outbound: {}) with {:?}",
            svr_cfg.addr(),
            svr_cfg.tcp_external_addr(),
            opts
        );

        Ok(Self::from_stream(context, map_fn(stream), svr_cfg, addr))
    }

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Verify the server address/port are correct and the server is reachable (`ping`/`nc -vz host port`)
  2. Increase connect_timeout in the server config if the network is slow but functional
  3. Check local firewall/VPN rules and the network path to the server
  4. If the server IP is blocked, change the server IP/port or use a different transport (e.g. plugin)
  5. Retry — transient outages or network switches often resolve on a fresh attempt

Example fix

// before
ServerConfig::new(addr, password, method.clone()) // default/no timeout tuning
// after
let mut sc = ServerConfig::new(addr, password, method.clone());
sc.set_connect_timeout(Some(Duration::from_secs(10))); // allow slow links
Defensive patterns

Strategy: retry

Validate before calling

// Probe server reachability before starting the client
let addr = svr_cfg.addr();
match tokio::time::timeout(
    Duration::from_secs(connect_timeout_secs),
    tokio::net::TcpStream::connect(addr),
).await {
    Ok(Ok(_)) => { /* proceed */ }
    _ => eprintln!("warning: server {} unreachable, check address/firewall", addr),
}

Try / catch

match client.connect(&opts).await {
    Err(e) if e.kind() == std::io::ErrorKind::TimedOut && e.to_string().starts_with("connect ") => {
        backoff_retry(|| client.connect(&opts), 3, Duration::from_secs(2)).await
    }
    r => r,
}

Prevention

When it happens

Trigger: connect_with_opts_map connects to svr_cfg.addr() while connect_timeout elapses: server IP unreachable (firewall drops SYN), wrong server address/port in config, network outage, or server overloaded and not accepting connections.

Common situations: Server blocked by GFW/firewall silently dropping packets; typo in server host/port; server process down; switching networks (WiFi→cellular) with stale routing; DNS resolving to an unreachable IP.

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 shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/d5a54f839645bdfd. Report an issue: GitHub.