nautechsystems/nautilus_trader · error

Bybit execution shutdown failed: {}

Error message

Bybit execution shutdown failed: {}

What it means

Aggregated error raised when the Bybit execution client fails to cleanly tear down during connect/disconnect. Individual shutdown step failures are collected in shutdown_errors and joined into a single bail after set_disconnected().

Source

Thrown at crates/adapters/bybit/src/execution.rs:315

            self.shutdown_errors
                .push(format!("trade WebSocket shutdown failed: {e}"));
        }
        self.dispatch_state.clear_repay_sender();

        if let Err(e) = self.await_session_tasks().await {
            self.shutdown_errors.push(e.to_string());
        }

        if let Err(e) = self.await_pending_tasks().await {
            self.shutdown_errors.push(e.to_string());
        }
        self.core.set_disconnected();

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

    /// Polls the cache until the account is registered or timeout is reached.
    async fn await_account_registered(&self, timeout_secs: f64) -> anyhow::Result<()> {
        let account_id = self.core.account_id;

        if self.core.cache().account(&account_id).is_some() {
            log::info!("Account {account_id} registered");
            return Ok(());
        }

        let start = Instant::now();
        let timeout = Duration::from_secs_f64(timeout_secs);
        let interval = Duration::from_millis(10);

        loop {
            tokio::time::sleep(interval).await;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the joined error message to identify which teardown step failed
  2. Check network connectivity and Bybit API status before reconnecting
  3. Retry disconnect(); the client should still be marked disconnected so a fresh connect is possible
  4. Enable debug logging on the Bybit execution client to see per-step shutdown failures
Defensive patterns

Strategy: retry

Try / catch

match exec_client.disconnect().await {
    Err(e) if e.to_string().starts_with("Bybit execution shutdown failed") => {
        tracing::warn!("shutdown partial failure: {e}; forcing reconnect");
        // client is already marked disconnected; proceed with a fresh connect
        exec_client.connect().await?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling connect() or disconnect() when teardown steps fail (e.g. WebSocket close errors, HTTP unsubscribe/cancel failures recorded during teardown).

Common situations: Network partitions during disconnect; venue returning errors on final REST calls; stale WebSocket connections that cannot be closed gracefully.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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