nautechsystems/nautilus_trader · error · anyhow::Error
Handler not available for Spot JSON pool slot
Error message
Handler not available for Spot JSON pool slot {slot_idx}: {e} What it means
subscribe() sends a Subscribe command to the handler task of the selected slot via its cmd_tx channel. This error means that send failed because the slot's handler task is no longer running (channel closed), even though the slot entry still exists in the pool.
Solutions
- Retry subscribe() so the pool can reconnect the dead slot via create_connection before dispatching.
- Check application logs for the handler task's exit reason (WS error, panic) and fix the root disconnect cause.
- Ensure shutdown is not concurrently tearing down handlers while subscribe() runs.
- If persistent, recreate the client/pool to rebuild all slots from scratch.
Example fix
// before
client.subscribe(streams).await?; // Err: Handler not available for slot 2
// after
match client.subscribe(streams).await {
Err(e) if e.to_string().contains("Handler not available") => {
tokio::time::sleep(Duration::from_secs(1)).await;
client.subscribe(streams).await?; // reconnects dead slot
}
r => r?,
} Defensive patterns
Strategy: retry
Try / catch
match client.subscribe(streams).await {
Err(e) if e.to_string().contains("Handler not available") => {
tokio::time::sleep(Duration::from_secs(1)).await;
client.subscribe(streams).await?; // pool reconnects dead slot
}
r => r?,
} Prevention
- Monitor handler task liveness and reconnect dead slots proactively.
- Fix root disconnect causes (network stability, keep-alive/ping configuration).
- Avoid subscribing while pool shutdown is in progress.
- Recreate the client if a slot stays dead across retries.
When it happens
Trigger: A slot's WebSocket handler task has exited (connection dropped terminally, task panicked, or pool partially shut down) and then subscribe() tries to route new streams to that dead slot.
Common situations: Network loss or Binance disconnect that permanently killed one handler while the pool bookkeeping still lists the slot; shutdown racing subscribe; a reconnect bug leaving a slot without a live handler.
Related errors
- Failed to send UpdateInstrument command
- Binance Spot public JSON stream pool shutdown began during…
- Derive execution startup teardown failed
- {e}
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/29c7e6214be3d774.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/spot/websocket/public_json/client.rs:399
})?;
slot_counts[slot_idx] += 1;
if let Some(batch) = slot_batches.iter_mut().find(|(i, _)| *i == slot_idx) {
batch.1.push(stream.clone());
} else {
slot_batches.push((slot_idx, vec![stream.clone()]));
}
}
for (slot_idx, batch) in &slot_batches {
slots[*slot_idx]
.cmd_tx
.send(BinanceSpotPublicWsCommand::Subscribe {
streams: batch.clone(),
})
.map_err(|e| {
anyhow::anyhow!("Handler not available for Spot JSON pool slot {slot_idx}: {e}")
})?;
slots[*slot_idx].streams.extend(batch.iter().cloned());
}
Ok(())
}
/// Unsubscribes from stream names.
///
/// # Errors
///
/// Returns an error if command delivery fails.
pub async fn unsubscribe(&self, streams: Vec<String>) -> anyhow::Result<()> {
if streams.is_empty() {
return Ok(());
}
let _connect_guard = self.connect_lock.lock().await;View on GitHub (pinned to 18893faf8b)