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
- Verify the server address/port are correct and the server is reachable (`ping`/`nc -vz host port`)
- Increase connect_timeout in the server config if the network is slow but functional
- Check local firewall/VPN rules and the network path to the server
- If the server IP is blocked, change the server IP/port or use a different transport (e.g. plugin)
- 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
- Set a realistic connect_timeout for slow networks (>= 5s on mobile)
- Monitor server availability and keep a fallback server list
- Verify server IP/port after any migration; silent SYN drops look exactly like this timeout
- Test reachability from the deployment network — blocked IPs fail with no other symptom
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- resolve empty
- protect() timeout
- invalid outbound_bind_addr
- resolve empty
- unexpected response from http://clients3.google.com/generate
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/d5a54f839645bdfd.
Report an issue: GitHub.