nautechsystems/nautilus_trader · error

Bybit data shutdown failed: {}

Error message

Bybit data shutdown failed: {}

What it means

teardown_partial_connect rolls back a partially completed Bybit data client connect: it stops tasks, closes sessions, and collects shutdown_errors. If any errors occurred while tearing down, it bails with all of them joined. This surfaces secondary failures that occurred while recovering from a failed connect.

Source

Thrown at crates/adapters/bybit/src/data.rs:422

            ws_client.begin_shutdown();
        }

        for ws_client in &mut self.ws_clients {
            if let Err(e) = ws_client.close().await {
                self.shutdown_errors.push(e.to_string());
            }
        }

        if let Err(e) = self.finish_tasks().await {
            self.shutdown_errors.push(e.to_string());
        }
        self.is_connected.store(false, Ordering::Release);

        if self.shutdown_errors.is_empty() {
            Ok(())
        } else {
            let errors = std::mem::take(&mut self.shutdown_errors);
            anyhow::bail!("Bybit data shutdown failed: {}", errors.join("; "))
        }
    }
}

fn send_data(sender: &tokio::sync::mpsc::UnboundedSender<DataEvent>, data: Data) {
    if let Err(e) = sender.send(DataEvent::Data(data)) {
        log::error!("Failed to emit data event: {e}");
    }
}

fn validate_orderbook_depth(depth: u32) -> anyhow::Result<()> {
    if !BYBIT_BOOK_DEPTHS.contains(&depth) {
        anyhow::bail!("invalid depth {depth}; valid values are {BYBIT_BOOK_DEPTHS:?}");
    }

    Ok(())
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the primary connect failure first (network, API credentials, region blocking)
  2. Check Bybit status and connectivity before retrying
  3. Retry connect after backoff; shutdown_errors are drained so a clean retry is safe
  4. If cleanup errors persist on a healthy network, report with full logs
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: verify API reachability and credentials before connect
assert!(bybit_reachable().await, "Bybit API unreachable");

Try / catch

loop {
    match client.connect().await {
        Ok(()) => break,
        Err(e) if attempts < MAX => { log::warn!("retrying after partial teardown: {e:#}"); attempts += 1; backoff(); }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: A connect attempt fails partway (e.g. session or command task startup fails) and cleanup itself encounters errors — such as failing to abort tasks or close websocket sessions — producing non-empty shutdown_errors.

Common situations: Unstable network during connect causing both startup failure and messy cleanup; exchange refusing connections so multiple subsystems error during rollback; calling connect repeatedly during an outage.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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