nautechsystems/nautilus_trader · critical
failed to connect Binance Futures private WebSocket
Error message
failed to connect Binance Futures private WebSocket
What it means
During user-data-stream recovery, `build_and_connect_user_stream` creates a fresh private WebSocket client for the Binance Futures listen-key stream and awaits `ws_client.connect()`. If the connect future resolves with an error (transport-level failure), the error is swallowed for logging and replaced with this generic anyhow error so `recover_with_retry` will re-attempt. It means the recovered private stream could not be established.
Solutions
- Check network connectivity to the Binance Futures WS endpoint (DNS, TLS, firewall/proxy); retry — `recover_with_retry` already schedules further attempts.
- Verify API key validity and that a valid listen-key was created (a bad key fails the stream after connect).
- Confirm no regional/IP restriction applies (Binance blocks some jurisdictions/IPs).
- Inspect the preceding `log::error!` output and enable debug logging for the underlying transport for the concrete cause.
Defensive patterns
Strategy: retry
Try / catch
// Recovery already retries via recover_with_retry; add bounded outer handling
match stream.recover_with_retry(max_attempts).await {
Ok(()) => {},
Err(e) if e.to_string().contains("failed to connect Binance Futures private WebSocket") => {
log::error!("recovery connect failed after retries: {e}; check network/listen-key");
// escalate: restart data engine or alert operator
}
Err(e) => return Err(e),
} Prevention
- Ensure outbound WSS (443) to Binance endpoints is allowed by firewall/proxy
- Monitor listen-key keepalive so recovery (and thus reconnects) is rare
- Verify API key validity and jurisdiction/IP accessibility of the endpoint
- Run reconnects with exponential backoff and alert after sustained failure
When it happens
Trigger: `recover_user_data_stream` (via `recover_with_retry`, typically after a -1125 listen-key invalidation/expiry or dropped connection) calls `connect`, and the WebSocket handshake fails — DNS failure, TLS error, proxy blocking wss://, or Binance endpoint unreachable.
Common situations: Network outage or firewall/proxy blocking the Binance WS endpoint during recovery; Binance regional endpoint blocked from your host (e.g. restricted jurisdiction); transient DNS failure; listen-key recreated but network flap at the same time.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- failed to connect Binance Futures market WebSocket
- failed to connect Binance Futures public WebSocket
- failed to connect Binance Spot public JSON WebSocket
- failed to connect Binance Spot SBE WebSocket
- Failed to connect Spot public JSON WS
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e74474786c8e0e03.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/futures/websocket/streams/recovery.rs:123
Some(BINANCE_WS_HEARTBEAT_SECS),
params.transport_backend,
)
.context("failed to construct Binance Futures private WebSocket client")?
.with_proxy(
params
.proxy_url
.as_ref()
.map(|value| value.expose_secret().to_owned()),
)
.with_socket_control(
params.socket_factory.clone(),
"binance-futures-user-streams",
);
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
+ CloneView on GitHub (pinned to 18893faf8b)