nautechsystems/nautilus_trader · error
failed to register Coinbase WebSocket consumption task
Error message
failed to register Coinbase WebSocket consumption task
What it means
This error is returned by spawn_ws when the Coinbase WebSocket consumption task fails to register with the session task spawner, but the rollback disconnect (ws_client.disconnect()) succeeded. The original spawn error is the source; the context indicates the startup was cleanly rolled back — no lingering connection should remain. It surfaces from connect().
Source
Thrown at crates/adapters/coinbase/src/data/mod.rs:303
log::debug!("WebSocket output channel closed");
break;
}
}
}
}
}
log::debug!("Coinbase WebSocket consumption loop finished");
};
if let Err(e) = self.session_tasks.spawn(future) {
if let Err(shutdown_error) = self.ws_client.disconnect().await {
return Err(anyhow::Error::new(e).context(format!(
"failed to register Coinbase WebSocket consumption task; startup rollback \
failed: {shutdown_error}"
)));
}
return Err(anyhow::Error::new(e)
.context("failed to register Coinbase WebSocket consumption task"));
}
log::debug!("WebSocket consumption task registered");
Ok(())
}
async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {
self.cancellation_token.cancel();
self.session_tasks.begin_shutdown();
self.command_tasks.begin_shutdown();
self.deriv_polls.shutdown();
self.ws_client.begin_shutdown();
let (tasks_result, polls_result) =
tokio::join!(self.finish_tasks(), self.deriv_polls.finish_shutdown());
if let Err(e) = tasks_result {
self.shutdown_errors.push(e.to_string());View on GitHub (pinned to 18893faf8b)
Solutions
- Fix client lifecycle: create and connect the client within a live session scope, don't reuse after shutdown
- Check the chained spawn error source for the task-group failure reason
- Ensure the tokio runtime is alive and not being torn down during connect()
- Retry connect() with a freshly constructed data client
- Look for concurrent connect/shutdown calls racing on the same client
Defensive patterns
Strategy: try-catch
Validate before calling
// Guard: only connect a client with a live session and runtime
if session_is_closed() || runtime_is_shutting_down() {
return Err(anyhow!("refusing to connect Coinbase data client during shutdown"));
} Type guard
fn is_clean_rollback(err: &anyhow::Error) -> bool {
err.to_string().contains("failed to register Coinbase WebSocket consumption task")
&& !err.to_string().contains("startup rollback failed")
} Try / catch
match connect(client).await {
Err(e) if is_clean_rollback(&e) => {
// spawn failed but disconnect succeeded: safe to retry with fresh client
retry_with_backoff(|| connect(new_client())).await
}
other => other,
} Prevention
- Create and connect data clients strictly within the live session lifecycle
- Don't reuse clients after their session task group is dropped
- Check the chained spawn error to diagnose task-group closure
- Serialize connect/shutdown operations on the same client
When it happens
Trigger: session_tasks.spawn(future) returns Err (closed/aborted task group, runtime shutdown) while self.ws_client.disconnect().await succeeds.
Common situations: Connecting a Coinbase data client after its session task group was dropped; tokio runtime cancellation during startup; calling connect() concurrently with shutdown; lifecycle misuse of the live data client.
Related errors
- failed to register Coinbase WebSocket consumption task; star
- Failed to start Spot public JSON WS bytes task: {e}
- Failed to start Spot public JSON WS handler task: {e}
- Coinbase WebSocket handler failed: {error}
- Coinbase WebSocket handler did not stop after abort
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/934af7b4f107e935.
Report an issue: GitHub.