{"record":{"id":"e74474786c8e0e03","repo":"nautechsystems/nautilus_trader","slug":"failed-to-connect-binance-futures-private-websocke","errorCode":null,"errorMessage":"failed to connect Binance Futures private WebSocket","messagePattern":"failed to connect Binance Futures private WebSocket","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/websocket/streams/recovery.rs","lineNumber":105,"sourceCode":"    let private_url =\n        get_futures_user_stream_url(params.product_type, &params.private_base_url, listen_key);\n\n    let mut ws_client = BinanceFuturesWebSocketClient::new(\n        params.product_type,\n        params.environment,\n        Some(params.api_key.clone()),\n        Some(params.api_secret.clone()),\n        Some(private_url),\n        Some(20),\n        params.transport_backend,\n    )\n    .context(\"failed to construct Binance Futures private WebSocket client\")?\n    .with_proxy(params.proxy_url.clone());\n\n    log::debug!(\"Connecting to Binance Futures user data stream...\");\n    ws_client.connect().await.map_err(|_| {\n        log::error!(\"Binance Futures private WebSocket connection failed\");\n        anyhow::anyhow!(\"failed to connect Binance Futures private WebSocket\")\n    })?;\n    log::debug!(\"Connected to Binance Futures user data stream\");\n\n    Ok(ws_client)\n}\n\n/// Long-lived task that consumes recovery signals and runs\n/// [`recover_user_data_stream`] with retry-on-failure semantics.\npub(crate) async fn run_recovery_driver<F>(\n    ctx: RecoveryCtx,\n    mut rx: tokio::sync::mpsc::UnboundedReceiver<()>,\n    cancel: CancellationToken,\n    dispatch_fn: F,\n) where\n    F: Fn(BinanceFuturesWsStreamsMessage, &DispatchCtx, &tokio::sync::mpsc::UnboundedSender<()>)\n        + Send\n        + Sync\n        + Clone","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/futures/websocket/streams/recovery.rs#L87-L123","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Enable debug/error logging and look at the surrounding WebSocket client logs, since the message itself omits the cause","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","Verify network egress to the Binance Futures WebSocket endpoint, including proxy settings, with a manual connect","For transient issues, let the recovery driver retry; if it never succeeds, fix credentials/network and restart the trading node"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Pre-flight: verify credentials can obtain a listenKey before starting the node\nimport requests\nresp = requests.post(\n    \"https://fapi.binance.com/fapi/v1/listenKey\",\n    headers={\"X-MBX-APIKEY\": api_key},\n    timeout=10,\n)\nresp.raise_for_status()  # 401/403 here predicts the private WS connect failing","typeGuard":null,"tryCatchPattern":"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.","preventionTips":["Pre-flight the API key with a listenKey REST call at startup","Confirm Futures permission and IP whitelist for the key on this host","Monitor disconnect/recovery metrics and alert on repeated reconnect failures"],"tags":["binance","futures","websocket","connection","user-data-stream","authentication"],"backgroundTag":"websocket-connection-failed","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}