nautechsystems/nautilus_trader · error · anyhow::Error
Binance Spot data teardown failed: {}
Error message
Binance Spot data teardown failed: {} What it means
Raised in `teardown_partial_connect` of the Binance Spot data client when one or more teardown/shutdown tasks (e.g. websocket disconnections, stream shutdowns) fail while cleaning up a partially established or closing connection. The client accumulates each failure message in `shutdown_errors`, marks itself disconnected, and bails with all messages joined by '; '. It signals that a disconnect or partial connect cleanup did not fully succeed, though the client is still flagged offline.
Source
Thrown at crates/adapters/binance/src/spot/data.rs:341
}
async fn teardown_partial_connect(&mut self) -> anyhow::Result<()> {
self.session_tasks.begin_shutdown();
self.command_tasks.begin_shutdown();
self.ws_client.begin_shutdown();
if let Err(e) = self.ws_client.close().await {
self.shutdown_errors
.push(format!("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 Spot data teardown failed: {}", errors.join("; "));
}
Ok(())
}
#[expect(clippy::too_many_arguments)]
async fn refresh_instrument_catalog(
http: &BinanceSpotHttpClient,
provider: &crate::config::BinanceInstrumentProviderConfig,
us: bool,
instruments_cache: &Arc<AtomicMap<InstrumentId, InstrumentAny>>,
status_cache: &Arc<AtomicMap<InstrumentId, MarketStatusAction>>,
ws: &SpotWsClient,
sender: &tokio::sync::mpsc::UnboundedSender<DataEvent>,
clock: &'static AtomicTime,
emit_status_changes: bool,
) -> anyhow::Result<Vec<InstrumentAny>> {
let instruments = http
.request_instruments_with_config(provider, us)View on GitHub (pinned to 18893faf8b)
Solutions
- Read the joined messages after the prefix to identify which teardown step(s) failed; the client is already marked disconnected so reconnect via `connect()` is usually safe
- Check network/proxy reachability to Binance endpoints (api.binance.com, ws streams) at the time of teardown
- Increase any disconnect/shutdown timeout in the adapter config so slow closes are not aborted
- Retry disconnect once; transient network errors during close are common and often succeed on retry
- If errors persist on every disconnect, enable debug logging and report the specific failing shutdown task
Example fix
// before
data_client.disconnect().await.unwrap();
// after
if let Err(e) = data_client.disconnect().await {
log::warn!("Binance Spot data teardown issue (client still disconnected): {e:#}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// before disconnecting, confirm network reachability
// ping Binance REST endpoint with a short timeout
let ok = tokio::time::timeout(Duration::from_secs(5), reqwest::get("https://api.binance.com/api/v3/ping")).await.is_ok(); Try / catch
match client.disconnect().await {
Ok(()) => {},
Err(e) if e.to_string().contains("teardown failed") => {
// client is already flagged disconnected; log and proceed with reconnect
log::warn!("teardown error (non-fatal): {e:#}");
}
Err(e) => return Err(e),
} Prevention
- Disconnect while network connectivity is confirmed healthy
- Allow generous shutdown timeouts for websocket/stream closes
- Inspect shutdown_errors messages to identify the failing teardown task and address it at the source
When it happens
Trigger: Calling `disconnect()` (or a `connect()` that fails partway and runs cleanup via `prepare_task_groups`) while websocket/stream shutdown tasks return errors; each failed shutdown pushes `e.to_string()` into `shutdown_errors`, and if non-empty the joined message is raised.
Common situations: Network outage or proxy drop during disconnect causing ws close to fail; Binance REST 4xx/5xx on session-termination calls; timeouts when closing streams on a slow connection; cancelling `connect()` mid-way so cleanup tasks run against half-initialized state.
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
- Failed to send message: {e}
- Binance Futures data teardown failed: {}
- WS modify order failed: {e}
- WS submit order failed: {e}
- WS cancel order failed: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e12932b343c3a046.
Report an issue: GitHub.