nautechsystems/nautilus_trader · error

failed to register Coinbase WebSocket consumption task; star

Error message

failed to register Coinbase WebSocket consumption task; startup rollback failed: {shutdown_error}

What it means

This error is returned by spawn_ws when the Coinbase WebSocket consumption task cannot be registered with the session task spawner AND the rollback (ws_client.disconnect()) also fails. The original spawn error is preserved as the source, with the disconnect failure appended to the context, so the caller knows both the connection setup failed and the client may still be connected. It surfaces from connect().

Source

Thrown at crates/adapters/coinbase/src/data/mod.rs:298

                    }
                    msg_opt = out_rx.recv() => {
                        match msg_opt {
                            Some(msg) => dispatch_ws_message(msg, &data_sender, &status_subs),
                            None => {
                                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();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the chained source error to distinguish the spawn failure from the disconnect failure
  2. Ensure connect() is called before any session teardown — do not reuse a data client whose task session is closed
  3. Manually force-disconnect/reset the ws_client to clear the possibly-still-open connection
  4. Recreate the Coinbase data client instance rather than reconnecting a partially-initialized one
  5. Check for runtime shutdown races (e.g. stopping the live node during connect)
Defensive patterns

Strategy: try-catch

Validate before calling

// Only connect within a live session scope
if session_is_closed() {
    return Err(anyhow!("cannot connect Coinbase data client: session already closed"));
}

Type guard

fn is_rollback_failure(err: &anyhow::Error) -> bool {
    err.to_string().contains("startup rollback failed")
}

Try / catch

match connect(client).await {
    Err(e) if e.to_string().contains("startup rollback failed") => {
        // connection AND cleanup failed: force reset the client
        client.force_disconnect()?;
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: session_tasks.spawn(future) returns Err (e.g. the runtime/session task group is already closed or aborted), and the subsequent self.ws_client.disconnect().await also returns Err.

Common situations: Calling connect() after the live runner's task session was shut down; tokio runtime shutting down concurrently; ws_client in a broken state where disconnect itself errors (already-closed transport, poisoned state); bugs in task-group lifecycle management.

Related errors


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