nautechsystems/nautilus_trader · error · anyhow::Error

Binance Spot public JSON stream pool shutdown began during c

Error message

Binance Spot public JSON stream pool shutdown began during connect; rollback failed: {e}

What it means

This error means the public JSON stream pool began shutting down while a new connect() call was in flight. The client detects the shutdown flag mid-connect and attempts to roll back by closing any connections it already opened; if rollback itself fails, the rollback error is embedded in this message. It is a race-condition guard so a connecting client never leaks connections during shutdown.

Source

Thrown at crates/adapters/binance/src/spot/websocket/public_json/client.rs:207

        let (out_tx, out_rx) = tokio::sync::mpsc::unbounded_channel();
        *self.out_tx.lock() = Some(out_tx);
        *self.out_rx.lock() = Some(out_rx);

        let slot = self.create_connection(0).await?;
        let shutdown = {
            let mut slots = self.slots.lock();
            let shutdown = self.signal.load(Ordering::Acquire);
            slots.push(slot);
            shutdown
        };

        if shutdown {
            let rollback = self.close_connections().await;
            return Err(match rollback {
                Ok(()) => anyhow::anyhow!(
                    "Binance Spot public JSON stream pool shutdown began during connect"
                ),
                Err(e) => anyhow::anyhow!(
                    "Binance Spot public JSON stream pool shutdown began during connect; rollback failed: {e}"
                ),
            });
        }

        log::debug!(
            "Connected to Binance Spot public JSON stream pool: url={}",
            self.url
        );
        Ok(())
    }

    /// Closes all WebSocket connections and tasks.
    ///
    /// # Errors
    ///
    /// Returns an error if command delivery fails while shutting down.
    pub async fn close(&mut self) -> anyhow::Result<()> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Serialize pool lifecycle: ensure shutdown/close_connections() is not called until all connect() futures complete (await the connect handles before stopping).
  2. Re-check pool state after connect and treat this error as expected during shutdown; do not retry connect if shutdown was intentional.
  3. If the rollback failure matters, inspect the embedded {e} (usually a send-on-closed-channel to a dead handler) and ensure handlers are dropped after close_connections completes.
  4. Use a shutdown-aware wrapper that suppresses this error once the pool's shutdown flag is observed.

Example fix

// before
let pool = client.clone();
tokio::spawn(async move { pool.connect().await });
pool.close_connections().await?;

// after
let handle = tokio::spawn(client.clone().connect());
// wait for in-flight connects before shutting down
let _ = handle.await;
client.close_connections().await?;
Defensive patterns

Strategy: try-catch

Validate before calling

if pool.is_shutdown() {
    return; // do not attempt connect during shutdown
}

Try / catch

match client.connect().await {
    Err(e) if e.to_string().contains("shutdown began during connect") => {
        log::debug!("connect aborted by shutdown: {e}"); // expected during teardown
    }
    Err(e) => return Err(e),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: Calling connect() on BinanceSpotPublicJsonWsClient while another task is concurrently calling close_connections()/shutdown on the same pool, so the shutdown flag flips between the initial check and the end of connect.

Common situations: Application teardown (actor stop, SIGTERM handling, subscription cancellation) racing a startup sequence that is still establishing streams; tests or live loops that restart the data engine while initial connects are pending.

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/fce14aeef2b8a6ae. Report an issue: GitHub.