nautechsystems/nautilus_trader · error

Failed to start Spot public JSON WS bytes task: {e}

Error message

Failed to start Spot public JSON WS bytes task: {e}

What it means

In create_connection, spawning the bytes-reading task for a public JSON WS slot failed (the spawn/send error `e`); the code rolls back by finishing the already-created handler task and bails. If the rollback itself also errors, the message appends 'startup rollback failed' with that shutdown error. Either way the slot connection was not established.

Source

Thrown at crates/adapters/binance/src/spot/websocket/public_json/client.rs:579

        let mut bytes_task = TaskSlot::new();
        if let Err(e) = bytes_task.spawn(async move {
            let mut raw_rx = raw_rx;
            while let Some(msg) = raw_rx.recv().await {
                let data = match msg {
                    Message::Binary(data) => data.to_vec(),
                    Message::Text(text) => text.as_bytes().to_vec(),
                    Message::Close(_) => break,
                    Message::Ping(_) | Message::Pong(_) | Message::Frame(_) => continue,
                };

                if bytes_tx.send(data).is_err() {
                    break;
                }
            }
        }) {
            let shutdown_error = finish_slot_task(&mut bytes_task, "Binance Spot WS bytes").await;
            anyhow::bail!(match shutdown_error {
                Some(shutdown_error) => format!(
                    "Failed to start Spot public JSON WS bytes task: {e}; startup rollback failed: \
                     {shutdown_error}"
                ),
                None => format!("Failed to start Spot public JSON WS bytes task: {e}"),
            });
        }

        let mut handler = BinanceSpotPublicWsHandler::new(
            self.signal.clone(),
            cmd_rx,
            bytes_rx,
            subscriptions_state.clone(),
            self.request_id_counter.clone(),
        );

        cmd_tx
            .send(BinanceSpotPublicWsCommand::SetClient(client))

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Retry connect/subscribe — if the failure was transient (network/runtime hiccup), a fresh create_connection usually succeeds.
  2. Verify the tokio runtime is alive and not shutting down when creating connections.
  3. Check the rollback suffix in the message: if 'startup rollback failed' appears, there are leaked task resources to investigate.
  4. Check network reachability to Binance and proxy/firewall settings before retrying.
Defensive patterns

Strategy: retry

Try / catch

for attempt in 0..3 {
    match client.connect().await {
        Ok(()) => break,
        Err(e) if e.to_string().contains("bytes task") && attempt < 2 => tokio::time::sleep(backoff(attempt)).await,
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: create_connection (called by connect and subscribe adding a new slot) failing when the bytes task cannot be spawned or immediately errors — e.g. tokio runtime shutdown, spawn failure, or the WS read stream erroring at start.

Common situations: Starting connections inside a runtime that is shutting down; resource exhaustion (task limits); a WebSocket already broken by network failure so the bytes task dies instantly at startup.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ea3b1f8b861c8e57. Report an issue: GitHub.