nautechsystems/nautilus_trader · error
Failed to terminate Coinbase session tasks: {e}
Error message
Failed to terminate Coinbase session tasks: {e} What it means
`await_session_tasks` shuts down the execution client's session-task set (WebSocket user-data session tasks) with the same 1s drain / 2s timeout, invoked from connect. Any failure from finish_shutdown is wrapped in this error.
Source
Thrown at crates/adapters/coinbase/src/execution.rs:264
self.session_tasks.begin_shutdown();
self.ws_user.begin_shutdown();
}
async fn await_pending_tasks(&self) -> anyhow::Result<()> {
self.pending_tasks.begin_shutdown();
self.pending_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
.await
.map_err(|e| anyhow::anyhow!("Failed to terminate Coinbase execution tasks: {e}"))?;
Ok(())
}
async fn await_session_tasks(&self) -> anyhow::Result<()> {
self.session_tasks.begin_shutdown();
self.session_tasks
.finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))
.await
.map_err(|e| anyhow::anyhow!("Failed to terminate Coinbase session tasks: {e}"))?;
Ok(())
}
async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {
self.abort_session_tasks();
self.abort_pending_tasks();
if let Err(e) = self.ws_user.disconnect().await {
self.shutdown_errors.push(e.to_string());
}
let (session_result, pending_result) =
tokio::join!(self.await_session_tasks(), self.await_pending_tasks());
self.core.set_disconnected();
if let Err(e) = session_result {
self.shutdown_errors.push(e.to_string());
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Wait and retry connect so the old session fully tears down
- Check logs for the hung session task / WebSocket read stall
- Confirm the WebSocket endpoint is reachable
- Recreate the client if session task state is wedged
- Increase the shutdown timeout if hangs are environmental
Example fix
// before
loop { client.connect().await?; } // hot reconnect loop
// after
loop {
client.connect().await?;
tokio::time::sleep(Duration::from_secs(1)).await; // allow teardown
} Defensive patterns
Strategy: retry
Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("Failed to terminate Coinbase session tasks") => {
tokio::time::sleep(Duration::from_secs(2)).await;
client.connect().await?; // retry once after teardown settles
}
other => other?,
} Prevention
- Detect dead WebSocket connections quickly with heartbeats
- Avoid reconnect storms; use capped backoff
- Ensure the runtime is not starved (block_in_place misuse) so tasks can finish
When it happens
Trigger: connect() called while the prior WebSocket user-data session tasks are still terminating and one hangs or panics beyond the 2-second timeout.
Common situations: Reconnecting after a WebSocket drop while the old session task is blocked reading a dead socket; runtime under load preventing graceful task completion.
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
- Polymarket RTDS task shutdown failed: {}
- RTDS connect was canceled by shutdown
- Architect AX data WebSocket handler failed: {error}
- Failed to finish Coinbase poll tasks: {e}
- Failed to terminate Coinbase execution tasks: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/69c50a3c10c0e317.
Report an issue: GitHub.