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
- Retry connect/subscribe — if the failure was transient (network/runtime hiccup), a fresh create_connection usually succeeds.
- Verify the tokio runtime is alive and not shutting down when creating connections.
- Check the rollback suffix in the message: if 'startup rollback failed' appears, there are leaked task resources to investigate.
- 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
- Create WS connections only on a healthy, non-shutting-down tokio runtime.
- Verify network/proxy reachability to Binance before initializing streams.
- Watch for 'startup rollback failed' in the message — it signals resource leaks needing deeper investigation.
- Use bounded retry with backoff around connection startup.
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
- Failed to start Spot public JSON WS handler task: {e}
- WS submit order failed: {e}
- WS cancel order failed: {e}
- WS modify order failed: {e}
- WS setup error channel closed
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ea3b1f8b861c8e57.
Report an issue: GitHub.