nautechsystems/nautilus_trader · error · anyhow::Error

L3 WebSocket failed to become active: {e}

Error message

L3 WebSocket failed to become active: {e}

What it means

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.

Source

Thrown at crates/adapters/kraken/src/data/spot.rs:347

            self.l3_handler_task = self.spawn_l3_handler_task(ws_l3.clone(), false);
            self.ws_l3 = Some(ws_l3);
        } else if handler_finished && let Some(ws_l3) = self.ws_l3.as_ref() {
            let ws_l3 = ws_l3.clone();
            self.l3_handler_task = self.spawn_l3_handler_task(ws_l3, true);
        }

        let ws_l3 = self
            .ws_l3
            .as_ref()
            .expect("ws_l3 initialized above")
            .clone();

        self.spawn_ws(
            async move {
                ws_l3
                    .wait_until_active(10.0)
                    .await
                    .map_err(|e| anyhow::anyhow!("L3 WebSocket failed to become active: {e}"))?;
                ws_l3
                    .wait_until_authenticated(10.0)
                    .await
                    .map_err(|e| anyhow::anyhow!("L3 WebSocket failed to authenticate: {e}"))?;
                ws_l3
                    .subscribe_book_l3(symbol_ustr, depth)
                    .await
                    .map_err(|e| anyhow::anyhow!("{e}"))
            },
            "subscribe l3 book",
        );

        Ok(())
    }

    fn spawn_l3_handler_task(
        &self,
        handler_client: KrakenSpotWebSocketClient,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify basic connectivity to Kraken's v2 WebSocket endpoint (curl/TLS handshake, proxy reachability) and fix network/proxy settings.
  2. Check logs for the earlier 'L3 WebSocket connect failed' error from the spawned L3 handler task — fix that root cause first.
  3. If behind a corporate proxy, set config.proxy_url correctly for the L3 client.
  4. Retry the subscription; transient Kraken connection slowness can exceed the fixed 10s window.
  5. Confirm the runtime (tokio) is not starved — a blocked executor can prevent the handler task from completing the handshake.

Example fix

// before
self.spawn_ws(async move {
    ws_l3.wait_until_active(10.0).await
        .map_err(|e| anyhow::anyhow!("L3 WebSocket failed to become active: {e}"))?;
    ...
});
// after (caller retries with backoff on transient network issues)
match client.subscribe_book_deltas(&cmd) {
    Err(e) if e.to_string().contains("failed to become active") => {
        tokio::time::sleep(Duration::from_secs(2)).await;
        client.subscribe_book_deltas(&cmd)?;
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check connectivity to Kraken v2 WS before subscribing
async fn kraken_ws_reachable() -> bool {
    tokio::net::TcpStream::connect("ws.kraken.com:443").await.is_ok()
}
if !kraken_ws_reachable().await { /* defer or alert before subscribe_l3_book */ }

Try / catch

match client.subscribe_book_deltas(&cmd) {
    Err(e) if e.to_string().contains("failed to become active") => {
        // wait and retry with backoff; check handler-task logs for connect failure
        tokio::time::sleep(Duration::from_secs(2)).await;
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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 nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ed3c73a3b3303249. Report an issue: GitHub.