nautechsystems/nautilus_trader · error · anyhow::Error

Binance Spot shutdown failed: {}

Error message

Binance Spot shutdown failed: {}

What it means

Aggregate shutdown error for the Binance Spot execution client: `teardown_partial_connect` collects every failure that occurred while tearing down a partially-established connection (or during normal disconnect) into `shutdown_errors` and bails with all messages joined by "; ". It signals that one or more teardown steps (stream closures, unsubscriptions, connection cleanup) failed.

Source

Thrown at crates/adapters/binance/src/spot/execution.rs:818

                .push(format!("trading WebSocket shutdown failed: {e}"));
        }
        self.disconnect_us_user_data().await;

        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());
        }

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

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

#[async_trait(?Send)]
impl ExecutionClient for BinanceSpotExecutionClient {
    fn is_connected(&self) -> bool {
        self.core.is_connected()
    }

    fn client_id(&self) -> ClientId {
        self.core.client_id
    }

    fn account_id(&self) -> AccountId {
        self.core.account_id
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the joined sub-errors after 'Binance Spot shutdown failed:' to identify which teardown step(s) failed
  2. Address the root cause (usually the same network/auth problem that caused the connect/disconnect failure)
  3. Reconnect with a fresh ExecutionClient instance — the adapter state was reset via std::mem::take
  4. If disconnect errors are benign during shutdown, treat them as non-fatal for process exit but fix for long-running reconnect loops
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = client.disconnect().await {
    log::error!("shutdown incomplete: {e}");
    // recreate the client before next use
}

Prevention

When it happens

Trigger: `connect` or `disconnect` fails partway and invokes `teardown_partial_connect`; any teardown step pushes an error into `self.shutdown_errors`, producing this combined error at the end of teardown.

Common situations: Network already down when disconnecting (streams cannot be closed gracefully); connect failure mid-way (e.g. auth stream connected but market stream not), triggering partial teardown; broker/endpoint refusing close frames.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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