{"record":{"id":"67cb5172ae9393f9","repo":"nautechsystems/nautilus_trader","slug":"lighter-websocket-initial-connection-timeout-after","errorCode":null,"errorMessage":"Lighter WebSocket initial connection timeout after {} seconds","messagePattern":"Lighter WebSocket initial connection timeout after (.+?) seconds","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/websocket/client.rs","lineNumber":487,"sourceCode":"                .map(|value| value.expose_secret().to_owned()),\n        };\n        let connect = WebSocketClient::epoch_builder()\n            .config(cfg)\n            .epoch_handler(message_handler)\n            .rate_limiter(ws_message_rate_limiter(&self.url))\n            .initial_connect_retry_policy(Self::initial_connect_retry_policy())\n            .cancellation_token(cancellation_token.clone())\n            .maybe_state_sink(\n                self.socket_control\n                    .as_ref()\n                    .map(SocketControl::sink)\n                    .or_else(|| self.socket_sink.clone()),\n            )\n            .connect();\n        let client =\n            match tokio::time::timeout(Duration::from_secs(self.ws_timeout_secs), connect).await {\n                Ok(result) => result?,\n                Err(_) => anyhow::bail!(\n                    \"Lighter WebSocket initial connection timeout after {} seconds\",\n                    self.ws_timeout_secs,\n                ),\n            };\n\n        if cancellation_token.is_cancelled()\n            || generation != self.connection_generation.load(Ordering::Acquire)\n        {\n            client.disconnect().await;\n\n            anyhow::bail!(\"Lighter WebSocket initial connection cancelled\");\n        }\n\n        let (cmd_tx, cmd_rx) = tokio::sync::mpsc::unbounded_channel::<HandlerCommand>();\n        let (out_tx, out_rx) = tokio::sync::mpsc::unbounded_channel::<NautilusWsMessage>();\n\n        // Capture the connection-mode atomic before moving `client` into the\n        // SetClient command below.","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/websocket/client.rs#L469-L505","documentation":"Raised when the initial Lighter WebSocket connection does not complete within ws_timeout_secs. connect_with_cancellation wraps the connect future in tokio::time::timeout and bails with this message if the deadline expires. It means the TCP/TLS/WebSocket handshake to Lighter did not finish in time.","triggerScenarios":"Calling connect() when the wss handshake to the Lighter stream endpoint takes longer than the configured ws_timeout_secs — slow network, unreachable host, DNS delays, or a too-small timeout value.","commonSituations":"Misconfigured ws_timeout_secs (e.g. 5s) on a high-latency link; wrong stream URL pointing at a firewalled host; corporate proxy intercepting wss traffic; Lighter endpoint outage.","solutions":["Increase ws_timeout_secs in the WebSocket client configuration to accommodate your network latency.","Verify the stream URL (e.g. wss://mainnet.zklighter.elliot.ai/stream) is reachable: curl or wscat the endpoint.","Check DNS resolution and firewall/proxy rules for outbound wss traffic.","Check Lighter exchange status for outages; retry with backoff if the endpoint is down.","If using connect_with_cancellation, confirm the cancellation token wasn't cancelled mid-connect, which would also prevent completion."],"exampleFix":"// before\nlet client = LighterWebSocketClient::new(config_with(ws_timeout_secs: 5));\n\n// after\nlet client = LighterWebSocketClient::new(config_with(ws_timeout_secs: 30));","handlingStrategy":"retry","validationCode":"// preflight: endpoint reachability\n// tokio::net::TcpStream::connect((host, 443)).await? within your timeout budget","typeGuard":null,"tryCatchPattern":"const MAX_RETRIES: usize = 3;\nfor attempt in 1..=MAX_RETRIES {\n    match client.connect().await {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"initial connection timeout\") => {\n            tokio::time::sleep(Duration::from_secs(attempt * 2)).await;\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Set ws_timeout_secs generously (>=30s) for high-latency links","Health-check the wss URL in config before starting the node","Monitor exchange status pages for outages","Verify proxy/firewall allows outbound wss"],"tags":["websocket","timeout","network","rust"],"backgroundTag":"request-timeout","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}