nautechsystems/nautilus_trader · error

Failed to start Deribit session generation: {e}

Error message

Failed to start Deribit session generation: {e}

What it means

When connecting, session tasks must be started via `start_generation` after any stale session is awaited/aborted. If that call fails (manager not in a startable state — e.g. still shutting down or already open), execution.rs:493 returns this error and the connect aborts before authentication.

Source

Thrown at crates/adapters/deribit/src/execution.rs:493

            self.await_pending_tasks().await?;
            self.pending_tasks
                .start_generation()
                .map_err(|e| anyhow::anyhow!("Failed to start Deribit task generation: {e}"))?;
        }

        if !self.session_tasks.is_open() || !self.session_tasks.is_empty() {
            self.abort_session_tasks();

            if self.ws_client.is_active() {
                self.ws_client
                    .close()
                    .await
                    .context("failed to close stale Deribit WebSocket")?;
            }
            self.await_session_tasks().await?;
            self.session_tasks
                .start_generation()
                .map_err(|e| anyhow::anyhow!("Failed to start Deribit session generation: {e}"))?;
        } else if self.ws_client.is_active() {
            self.ws_client
                .close()
                .await
                .context("failed to close stale Deribit WebSocket")?;
        }
        let ws_client = self.ws_client.clone();
        let setup_guard =
            TaskGroupGuard::new(&[&self.session_tasks, &self.pending_tasks], move || {
                ws_client.begin_shutdown();
            });

        // Check if credentials are available before requesting account state
        if !self.config.has_api_credentials() {
            anyhow::bail!("Missing API credentials; set Deribit environment variables");
        }

        // Set account ID for order/fill reports

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Serialize `connect()` calls (mutex or single owner task) to avoid racing session-task state.
  2. On failure, call `abort_session_tasks()` then retry connect after a short backoff.
  3. Resolve any prior 'Failed to terminate Deribit session tasks' error before reconnecting.
  4. Verify teardown logic always leaves the session-task manager in a startable (closed/empty) state.

Example fix

// before
if let Err(e) = client.connect().await {
    panic!("connect failed: {e}");
}

// after
if let Err(e) = client.connect().await {
    if e.to_string().contains("Failed to start Deribit session generation") {
        client.abort_session_tasks();
        tokio::time::sleep(Duration::from_millis(200)).await;
    }
    client.connect().await?;
}
Defensive patterns

Strategy: retry

Validate before calling

// Serialize connects and ensure prior teardown finished
let _guard = connect_mutex.lock().await;
if connect_in_flight.swap(true, Ordering::SeqCst) {
    return Err(anyhow!("connect already in progress"));
}

Try / catch

if let Err(e) = client.connect().await {
    if e.to_string().contains("Failed to start Deribit session generation") {
        client.abort_session_tasks();
        tokio::time::sleep(Duration::from_millis(500)).await;
        client.connect().await?;
    } else {
        return Err(e);
    }
}

Prevention

When it happens

Trigger: Calling `connect()` while session-task generation state is inconsistent: concurrent connects, or a prior shutdown that never fully completed leaving the manager non-startable.

Common situations: Simultaneous connect attempts from different parts of an application; reconnect immediately after a shutdown-timeout error without aborting session tasks; state machine misuse after partial connect teardown (`teardown_partial_connect`) followed by an immediate reconnect race.

Related errors


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