nautechsystems/nautilus_trader · error

Binance Futures data teardown failed: {}

Error message

Binance Futures data teardown failed: {}

What it means

Aggregated error from Binance Futures data client teardown: all errors collected while closing the market/public WebSockets and finishing task groups are joined and bailed as one message. It means the partial or full shutdown did not complete cleanly.

Source

Thrown at crates/adapters/binance/src/futures/data.rs:378

        if let Err(e) = self.ws_client.close().await {
            self.shutdown_errors
                .push(format!("market WebSocket close failed: {e}"));
        }

        if let Err(e) = self.ws_public_client.close().await {
            self.shutdown_errors
                .push(format!("public WebSocket close failed: {e}"));
        }

        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() {
            let errors = std::mem::take(&mut self.shutdown_errors);
            anyhow::bail!(
                "Binance Futures data teardown failed: {}",
                errors.join("; ")
            );
        }
        Ok(())
    }

    #[expect(clippy::too_many_arguments)]
    async fn refresh_instrument_catalog(
        http: &BinanceFuturesHttpClient,
        provider: &crate::config::BinanceInstrumentProviderConfig,
        instruments_cache: &Arc<AtomicMap<InstrumentId, InstrumentAny>>,
        status_cache: &Arc<AtomicMap<InstrumentId, MarketStatusAction>>,
        ws: &BinanceFuturesWebSocketClient,
        ws_public: &BinanceFuturesWebSocketClient,
        sender: &tokio::sync::mpsc::UnboundedSender<DataEvent>,
        clock: &'static AtomicTime,
        emit_status_changes: bool,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the joined message; it enumerates the specific sub-failures (market WS close, public WS close, task finish)
  2. Fix the root cause in the innermost error first (usually network or a hung task)
  3. Retry connect/disconnect after the network recovers; state is reset (is_connected=false) even on failure
  4. Avoid initiating new subscriptions while teardown is in progress
  5. Report/upgrade if WS close consistently times out
Defensive patterns

Strategy: try-catch

Validate before calling

// check connectivity before disconnect to avoid WS close errors
assert!(ws_health_check().await.is_ok(), "WebSocket must be responsive before teardown");

Try / catch

if let Err(e) = client.disconnect().await {
    log::error!("teardown: {e}"); // message lists each sub-failure
    // safe to retry: is_connected is already false
    client.disconnect().await?;
}

Prevention

When it happens

Trigger: teardown_partial_connect runs (during a failed connect, or explicit disconnect) and any of: ws_client.close(), ws_public_client.close(), or finish_tasks() returns an error; messages are pushed to shutdown_errors and bail if non-empty.

Common situations: Failed initial connect that must roll back subscriptions, disconnect during a network outage, hung WebSocket sockets, or a previously failed finish_tasks pushing errors into shutdown_errors.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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