{"record":{"id":"ed3c73a3b3303249","repo":"nautechsystems/nautilus_trader","slug":"l3-websocket-failed-to-become-active-e","errorCode":null,"errorMessage":"L3 WebSocket failed to become active: {e}","messagePattern":"L3 WebSocket failed to become active: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/kraken/src/data/spot.rs","lineNumber":347,"sourceCode":"            self.l3_handler_task = self.spawn_l3_handler_task(ws_l3.clone(), false);\n            self.ws_l3 = Some(ws_l3);\n        } else if handler_finished && let Some(ws_l3) = self.ws_l3.as_ref() {\n            let ws_l3 = ws_l3.clone();\n            self.l3_handler_task = self.spawn_l3_handler_task(ws_l3, true);\n        }\n\n        let ws_l3 = self\n            .ws_l3\n            .as_ref()\n            .expect(\"ws_l3 initialized above\")\n            .clone();\n\n        self.spawn_ws(\n            async move {\n                ws_l3\n                    .wait_until_active(10.0)\n                    .await\n                    .map_err(|e| anyhow::anyhow!(\"L3 WebSocket failed to become active: {e}\"))?;\n                ws_l3\n                    .wait_until_authenticated(10.0)\n                    .await\n                    .map_err(|e| anyhow::anyhow!(\"L3 WebSocket failed to authenticate: {e}\"))?;\n                ws_l3\n                    .subscribe_book_l3(symbol_ustr, depth)\n                    .await\n                    .map_err(|e| anyhow::anyhow!(\"{e}\"))\n            },\n            \"subscribe l3 book\",\n        );\n\n        Ok(())\n    }\n\n    fn spawn_l3_handler_task(\n        &self,\n        handler_client: KrakenSpotWebSocketClient,","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/kraken/src/data/spot.rs#L329-L365","documentation":"KrakenSpotDataClient::subscribe_l3_book spawns a task that must wait for the dedicated L3 WebSocket to become active before subscribing; `wait_until_active(10.0)` polls `is_active()` for 10 seconds and returns `KrakenWsError::ConnectionError(\"WebSocket connection timeout after 10 seconds\")` if it never does. The adapter wraps that timeout in this message. It means the L3 WebSocket connection (a separate client spawned for Level 3 data) never reached the active state within the 10s budget.","triggerScenarios":"Calling subscribe_book_deltas (L3 mode) when the underlying L3 KrakenSpotWebSocketClient fails to connect — network outage, DNS/proxy failure, Kraken endpoint down, or the spawned L3 handler task's connect() failed so `is_active()` never turns true within 10 seconds.","commonSituations":"No internet or firewall/proxy blocking wss://ws.kraken.com/v2; invalid proxy_url configured; Kraken WebSocket outage or rate-limiting new connections; machine clock/scheduling stalls under heavy backtest/live load so the 10s window elapses before the handshake completes.","solutions":["Verify basic connectivity to Kraken's v2 WebSocket endpoint (curl/TLS handshake, proxy reachability) and fix network/proxy settings.","Check logs for the earlier 'L3 WebSocket connect failed' error from the spawned L3 handler task — fix that root cause first.","If behind a corporate proxy, set config.proxy_url correctly for the L3 client.","Retry the subscription; transient Kraken connection slowness can exceed the fixed 10s window.","Confirm the runtime (tokio) is not starved — a blocked executor can prevent the handler task from completing the handshake."],"exampleFix":"// before\nself.spawn_ws(async move {\n    ws_l3.wait_until_active(10.0).await\n        .map_err(|e| anyhow::anyhow!(\"L3 WebSocket failed to become active: {e}\"))?;\n    ...\n});\n// after (caller retries with backoff on transient network issues)\nmatch client.subscribe_book_deltas(&cmd) {\n    Err(e) if e.to_string().contains(\"failed to become active\") => {\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        client.subscribe_book_deltas(&cmd)?;\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","handlingStrategy":"retry","validationCode":"// pre-check connectivity to Kraken v2 WS before subscribing\nasync fn kraken_ws_reachable() -> bool {\n    tokio::net::TcpStream::connect(\"ws.kraken.com:443\").await.is_ok()\n}\nif !kraken_ws_reachable().await { /* defer or alert before subscribe_l3_book */ }","typeGuard":null,"tryCatchPattern":"match client.subscribe_book_deltas(&cmd) {\n    Err(e) if e.to_string().contains(\"failed to become active\") => {\n        // wait and retry with backoff; check handler-task logs for connect failure\n        tokio::time::sleep(Duration::from_secs(2)).await;\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Verify network/proxy reachability to Kraken's v2 WebSocket endpoint before starting L3 sessions","Monitor adapter logs for 'L3 WebSocket connect failed' to catch root-cause connect errors early","Avoid starting L3 subscriptions on a saturated tokio runtime","Provide config.proxy_url when operating behind a corporate proxy"],"tags":["websocket","kraken","timeout","connection"],"backgroundTag":"request-timeout","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}