{"record":{"id":"89a89acc8f42da9e","repo":"cube-js/cube","slug":"connect-timeout","errorCode":null,"errorMessage":"connect timeout","messagePattern":"connect timeout","errorType":"exception","errorClass":"std::io::Error (ErrorKind::TimedOut, wrapped in TransportError::Connect)","httpStatus":null,"severity":"error","filePath":"rust/cube/cubestore-ws-transport/src/actor.rs","lineNumber":307,"sourceCode":"        .map_err(|e| TransportError::Auth(format!(\"x-process-id: {e}\")))?;\n    builder = builder.header(\"x-process-id\", value);\n\n    let request = builder\n        .body(())\n        .map_err(|e| TransportError::InvalidUrl(e.to_string()))?;\n\n    // Match cubestore's transport caps (default 64MiB message / 32MiB frame; the\n    // server can be configured up to 256MiB). The tungstenite default of 16MiB\n    // per frame is too tight for large query results.\n    let ws_config = WebSocketConfig::default()\n        .max_message_size(Some(256 << 20))\n        .max_frame_size(Some(256 << 20));\n    let connect_future = connect_async_with_config(request, Some(ws_config), false);\n    let (ws, response) = tokio::time::timeout(cfg.connect_timeout, connect_future)\n        .await\n        .map_err(|_| {\n            TransportError::Connect(tokio_tungstenite::tungstenite::Error::Io(\n                std::io::Error::new(std::io::ErrorKind::TimedOut, \"connect timeout\"),\n            ))\n        })??;\n\n    let version = response\n        .headers()\n        .get(\"X-CubeStore-Version\")\n        .or_else(|| response.headers().get(\"x-cubestore-version\"))\n        .and_then(|v| v.to_str().ok())\n        .map(|s| s.to_string());\n\n    Ok((ws, version))\n}\n\nfn build_ws_url(base: &url::Url) -> Result<url::Url, TransportError> {\n    let mut u = base.clone();\n    let path = u.path();\n\n    // If the user already pointed at /ws (or another explicit path), keep it.","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube/cubestore-ws-transport/src/actor.rs#L289-L325","documentation":"Cube Store's WebSocket transport wraps the WebSocket handshake in `tokio::time::timeout(cfg.connect_timeout)`. If the TCP/TLS/WS handshake does not complete within that window, the future is cancelled and the transport raises `TransportError::Connect` carrying an `io::Error` of kind `TimedOut` with message \"connect timeout\". It surfaces during initial `connect` and during `attempt_reconnect` loops.","triggerScenarios":"Connecting to a Cube Store endpoint whose host is unreachable (firewall dropping packets), wrong host/port in the connection URL, the Cube Store server process being down or overloaded, or a network with high latency exceeding `connect_timeout` (including during automatic reconnect attempts).","commonSituations":"Cube Store container not started or listening on a different port; Kubernetes/network-policy or cloud security group silently dropping SYNs; DNS resolving to a dead host; VPN or proxy latency; overly aggressive `connect_timeout` for a remote region.","solutions":["Verify the Cube Store host/port in the connection URL and confirm the server is running (`docker ps`, `kubectl get pods`, check the listener).","Test reachability from the client host: `nc -vz <host> <port>` or `curl -v http://<host>:<port>/ws`; if it hangs, fix firewall/security-group rules.","Increase the configured `connect_timeout` if the network is legitimately slow (cross-region, VPN).","Check reconnect/backoff settings if the error appears only during reconnection storms, and inspect Cube Store server logs for overload."],"exampleFix":"// before: too-tight timeout against a remote cluster\ncfg.connect_timeout = Duration::from_secs(2);\n// after\ncfg.connect_timeout = Duration::from_secs(30);","handlingStrategy":"retry","validationCode":"// Pre-flight reachability check before opening the transport:\nasync fn reachable(host: &str, port: u16, timeout: Duration) -> bool {\n    tokio::time::timeout(timeout, tokio::net::TcpStream::connect((host, port)))\n        .await\n        .map(|r| r.is_ok())\n        .unwrap_or(false)\n}","typeGuard":"fn is_connect_timeout(e: &TransportError) -> bool {\n    matches!(e, TransportError::Connect(\n        tokio_tungstenite::tungstenite::Error::Io(io))\n        if io.kind() == std::io::ErrorKind::TimedOut)\n}","tryCatchPattern":"// Match the error kind and retry with backoff:\nmatch connect(cfg).await {\n    Err(TransportError::Connect(e))\n        if matches!(&e, tungstenite::Error::Io(io) if io.kind() == std::io::ErrorKind::TimedOut) =>\n    {\n        tokio::time::sleep(backoff.next()).await;\n        retry_with_longer_timeout(cfg)\n    }\n    other => other,\n}","preventionTips":["Set `connect_timeout` generously (>=30s) for remote/VPN connections.","Monitor Cube Store availability and alert before clients time out.","Verify firewall/security-group rules allow the Cube Store port from client hosts.","Use exponential backoff with jitter on reconnects to avoid hammering a recovering server.","Health-check DNS resolution for the Cube Store host in your deployment."],"tags":["network","timeout","websocket","cubestore","connectivity"],"backgroundTag":"connect-timeout","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}