nautechsystems/nautilus_trader · critical
failed to connect Binance Futures public WebSocket: {e}
Error message
failed to connect Binance Futures public WebSocket: {e} What it means
Raised during `connect()` when the second WebSocket — the Binance Futures public market-data client — fails to connect, immediately after the market client succeeded. The underlying error is wrapped with anyhow and logged at ERROR level (`Binance Futures public WebSocket connection failed: {e:?}`). A failure here still fails the entire data client connect, leaving the node with no streams even though the first socket opened.
Source
Thrown at crates/adapters/binance/src/futures/data.rs:1540
&self.ws_client,
&self.ws_public_client,
&self.data_sender,
self.clock,
false,
)
.await?;
log::info!("Connecting to Binance Futures market WebSocket...");
self.ws_client.connect().await.map_err(|e| {
log::error!("Binance Futures market WebSocket connection failed: {e:?}");
anyhow::anyhow!("failed to connect Binance Futures market WebSocket: {e}")
})?;
log::info!("Binance Futures market WebSocket connected");
log::info!("Connecting to Binance Futures public WebSocket...");
self.ws_public_client.connect().await.map_err(|e| {
log::error!("Binance Futures public WebSocket connection failed: {e:?}");
anyhow::anyhow!("failed to connect Binance Futures public WebSocket: {e}")
})?;
log::info!("Binance Futures public WebSocket connected");
// Spawn market stream handler
let stream = self.ws_client.stream();
let sender = self.data_sender.clone();
let insts = self.instruments.clone();
let ws_insts = self.ws_client.instruments_cache();
let buffers = self.book_buffers.clone();
let book_subs = self.book_subscriptions.clone();
let l1_book_subs = self.l1_book_subscriptions.clone();
let force_order_refs = self.force_order_refs.clone();
let ticker_refs = self.ticker_refs.clone();
let force_order_all_market_refs = self.force_order_all_market_refs.clone();
let force_order_all_market_stream_active =
self.force_order_all_market_stream_active.clone();
let book_epoch = self.book_epoch.clone();
let http = self.http_client.clone();View on GitHub (pinned to a4b06ed870)
Solutions
- Inspect the wrapped `{e}` to distinguish timeout vs handshake rejection vs DNS failure
- Retry the full connect with backoff — both sockets are re-established on each attempt
- Reduce concurrent Binance WS connections (other clients/tabs/scripts) if hitting connection limits
- If persistent, verify the public stream host resolves and a plain TLS connection to port 443 succeeds from the same host
Example fix
# before: no tolerance for the second handshake failing
await node.run() # raises: failed to connect Binance Futures public WebSocket: {e}
# after: backoff around the whole connect sequence (both sockets)
for attempt in range(6):
try:
await node.run()
break
except Exception as e:
if 'failed to connect Binance Futures' not in str(e):
raise
await asyncio.sleep(min(2 ** attempt, 30)) Defensive patterns
Strategy: retry
Validate before calling
import socket
def binance_ws_reachable(host: str = 'fstream.binance.com', port: int = 443, timeout: float = 5.0) -> bool:
try:
with socket.create_connection((host, port), timeout=timeout):
return True
except OSError:
return False Try / catch
# public client connects right after the market client; retry the whole sequence
for attempt in range(6):
try:
await node.run()
break
except Exception as e:
if 'failed to connect Binance Futures public WebSocket' not in str(e):
raise
await asyncio.sleep(min(2 ** attempt, 30))
else:
raise RuntimeError('Binance Futures public WebSocket unreachable after retries') Prevention
- Keep concurrent Binance WebSocket connections low to avoid per-IP connection limits during reconnect storms
- Reuse a single data client for many instruments (combined streams) instead of many clients
- Treat back-to-back connect failures as environmental: test with a plain TLS handshake to the stream host
When it happens
Trigger: Same connect sequence as the market client, but the public stream host fails: transient network drop between the two handshakes, firewall/DNS issues specific to the public stream endpoint, Binance connection-limit or rate-limit rejections when too many sockets open rapidly, or region-blocked IPs.
Common situations: Flaky networking where the first connect succeeds and the second times out; hitting Binance's per-IP WebSocket connection limits during reconnect storms; CI environments with restricted egress; testnet public stream endpoints under maintenance.
Related errors
- failed to connect Binance Futures market WebSocket: {e}
- failed to connect Binance Futures private WebSocket
- failed to connect Binance Spot public JSON WebSocket: {e}
- WS modify order failed: {e}
- failed to connect Binance Spot SBE WebSocket: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/fefeab91476dae6e.
Report an issue: GitHub.