nautechsystems/nautilus_trader · critical

failed to connect Binance Futures market WebSocket: {e}

Error message

failed to connect Binance Futures market WebSocket: {e}

What it means

Raised during `connect()` when the Binance Futures market WebSocket client fails to establish its connection; the underlying transport error is wrapped with anyhow and also logged at ERROR level (`Binance Futures market WebSocket connection failed: {e:?}`) just above. Because this sits in the data client's connect sequence (after the instrument catalogue refresh), the whole connect fails and no streams start. The real cause is in the wrapped error: DNS/TLS/network failure, a firewall or proxy blocking wss, Binance rejecting the handshake, region-restricted access, or an endpoint/credential mismatch such as production keys against a testnet URL.

Source

Thrown at crates/adapters/binance/src/futures/data.rs:1533

        self.cancellation_token = CancellationToken::new();

        Self::refresh_instrument_catalogue(
            &self.http_client,
            &self.config.instrument_provider,
            &self.instruments,
            &self.status_cache,
            &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();

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Read the wrapped `{e}` in the log line above to identify the true cause (DNS vs TLS vs HTTP 401/403 vs timeout)
  2. Fix environment: ensure wss://fstream.binance.com (or the testnet host) is reachable from the host, open firewall/proxy, set HTTPS_PROXY if a proxy is required
  3. If the error is auth/region related (401/403): verify api_key/api_secret, enable futures permission on the key, and make sure testnet=True matches testnet keys
  4. Retry connect with exponential backoff for transient outages instead of crashing the node

Example fix

# before: single connect attempt, any hiccup kills startup
await node.run()  # connect raises: failed to connect Binance Futures market WebSocket: {e}

# after: correct environment matching + retry with backoff, abort on auth errors
config = BinanceFuturesDataClientConfig(
    api_key=os.environ['BINANCE_API_KEY'],
    api_secret=os.environ['BINANCE_API_SECRET'],
    testnet=True,  # must match the environment your keys belong to
)
for attempt in range(6):
    try:
        await node.run()
        break
    except Exception as e:
        msg = str(e)
        if '401' in msg or '403' in msg or 'signature' in msg.lower():
            raise RuntimeError('Binance auth/region problem: check keys, futures permission, testnet flag') from e
        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:
    """Preflight: can this host open a TCP connection to the WS endpoint?"""
    try:
        with socket.create_connection((host, port), timeout=timeout):
            return True
    except OSError:
        return False

if not binance_ws_reachable():
    raise RuntimeError('fstream.binance.com unreachable — fix network/firewall/region before starting the client')

Try / catch

# transient WS failures: retry the full connect with backoff; abort on auth/region causes
last = None
for attempt in range(6):
    try:
        await node.run()  # data client connect happens here
        break
    except Exception as e:
        if 'failed to connect Binance Futures market WebSocket' not in str(e):
            raise
        last = e
        if any(tok in str(e) for tok in ('401', '403', 'signature', 'Unauthorized')):
            raise RuntimeError('Binance rejected the WS handshake: check keys, futures permission, testnet flag, region access') from e
        await asyncio.sleep(min(2 ** attempt, 30))
else:
    raise last

Prevention

When it happens

Trigger: Engine connect with the Binance Futures data client while: the host (fstream.binance.com / testnet stream.binancefuture.com) is unreachable or DNS fails; a corporate firewall blocks outbound wss; the client IP is in a region Binance blocks for futures; an authenticated handshake fails (invalid API key/secret, key without futures permission, clock skew breaking signature); the `testnet` flag does not match the configured keys.

Common situations: US-based developer hitting Binance global futures endpoints (geo-blocked); testnet flag flipped but production keys kept; keys created for spot only; running in Docker/CI without network egress; transient Binance WebSocket outage or maintenance.

Related errors


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