nautechsystems/nautilus_trader · error · anyhow::Error

failed to connect Binance Futures private WebSocket

Error message

failed to connect Binance Futures private WebSocket

What it means

Raised when connect() on the Binance Futures private (user data) WebSocket fails while (re)establishing the stream during recovery. The underlying error is deliberately discarded from the message (map_err(|_| ...)) and only a separate error-level log line is emitted, so the real cause (auth, listenKey, network, proxy) must be found in the logs. The recovery driver (recover_with_retry) will retry the connection, so transient failures self-heal.

Source

Thrown at crates/adapters/binance/src/futures/websocket/streams/recovery.rs:105

    let private_url =
        get_futures_user_stream_url(params.product_type, &params.private_base_url, listen_key);

    let mut ws_client = BinanceFuturesWebSocketClient::new(
        params.product_type,
        params.environment,
        Some(params.api_key.clone()),
        Some(params.api_secret.clone()),
        Some(private_url),
        Some(20),
        params.transport_backend,
    )
    .context("failed to construct Binance Futures private WebSocket client")?
    .with_proxy(params.proxy_url.clone());

    log::debug!("Connecting to Binance Futures user data stream...");
    ws_client.connect().await.map_err(|_| {
        log::error!("Binance Futures private WebSocket connection failed");
        anyhow::anyhow!("failed to connect Binance Futures private WebSocket")
    })?;
    log::debug!("Connected to Binance Futures user data stream");

    Ok(ws_client)
}

/// Long-lived task that consumes recovery signals and runs
/// [`recover_user_data_stream`] with retry-on-failure semantics.
pub(crate) async fn run_recovery_driver<F>(
    ctx: RecoveryCtx,
    mut rx: tokio::sync::mpsc::UnboundedReceiver<()>,
    cancel: CancellationToken,
    dispatch_fn: F,
) where
    F: Fn(BinanceFuturesWsStreamsMessage, &DispatchCtx, &tokio::sync::mpsc::UnboundedSender<()>)
        + Send
        + Sync
        + Clone

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Enable debug/error logging and look at the surrounding WebSocket client logs, since the message itself omits the cause
  2. Verify the API key/secret pair is valid, Futures-enabled, and IP-whitelisted for this host by creating a listenKey via REST (POST /fapi/v1/listenKey) manually
  3. Verify network egress to the Binance Futures WebSocket endpoint, including proxy settings, with a manual connect
  4. For transient issues, let the recovery driver retry; if it never succeeds, fix credentials/network and restart the trading node
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight: verify credentials can obtain a listenKey before starting the node
import requests
resp = requests.post(
    "https://fapi.binance.com/fapi/v1/listenKey",
    headers={"X-MBX-APIKEY": api_key},
    timeout=10,
)
resp.raise_for_status()  # 401/403 here predicts the private WS connect failing

Try / catch

Treat connect failures as retryable with capped exponential backoff (the built-in recovery driver already does this); after N consecutive failures surface an operator alert instead of silently looping, and inspect error-level logs because the message omits the cause.

Prevention

When it happens

Trigger: build_and_connect_user_stream calls ws_client.connect() against the futures user-data URL (built from the listen key) and it fails: listenKey rejected (invalid API key/secret, key without Futures permission, IP restriction), DNS/firewall/proxy failure, or Binance endpoint outage.

Common situations: Rotated or expired API keys; API key IP whitelist excluding the host; egress firewalls in containers or corporate networks; misconfigured proxy_url; regional blocking of Binance futures endpoints.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/e74474786c8e0e03. Report an issue: GitHub.