nautechsystems/nautilus_trader · error
failed to connect Binance Spot public JSON WebSocket
Error message
failed to connect Binance Spot public JSON WebSocket: {e} What it means
The Binance Spot data client failed to establish the public JSON WebSocket connection during connect(). The underlying error is logged with debug detail and wrapped in an anyhow error, aborting the connect() session so no market data can stream.
Solutions
- Verify the WebSocket endpoint is reachable from your host (DNS + TCP + TLS).
- Check the debug log 'Binance Spot public JSON WebSocket connection failed: {e:?}' for the concrete cause.
- If geo-blocked (HTTP 451), deploy in a supported region.
- Retry with exponential backoff for transient Binance-side drops.
- Confirm the adapter is configured for the intended environment (prod vs testnet URL).
Example fix
// before
let client = BinanceSpotDataClient::new_json_public(config);
client.connect().await?;
// after
if let Err(e) = client.connect().await {
log::error!("spot JSON WS connect failed: {e:#}");
if e.to_string().contains("failed to connect Binance Spot public JSON WebSocket") {
tokio::time::sleep(Duration::from_secs(2)).await;
client.connect().await?;
} else {
return Err(e);
}
} Defensive patterns
Strategy: retry
Validate before calling
// pre-connect reachability probe
let host = "stream.binance.com";
tokio::net::TcpStream::connect((host, 9443)).await.expect("Binance JSON WS endpoint unreachable"); Type guard
fn is_json_ws_connect_error(err: &anyhow::Error) -> bool {
err.to_string().contains("failed to connect Binance Spot public JSON WebSocket")
} Try / catch
if let Err(e) = client.connect().await {
if is_json_ws_connect_error(&e) {
tokio::time::sleep(Duration::from_secs(5)).await;
client.connect().await?;
} else { return Err(e); }
} Prevention
- Verify endpoint reachability before building the data client.
- Distinguish transient (retryable) from permanent (config/geo) connect failures.
- Log the underlying {e:?} detail to diagnose TLS vs DNS vs HTTP rejection.
- Add automatic reconnect supervision to the data client.
When it happens
Trigger: Calling connect() when SpotWsClient is the JsonPublic variant and ws_client.connect() fails — network failure, TLS error, endpoint rejecting connection, or invalid stream URL.
Common situations: Firewall or corporate proxy blocking wss://stream.binance.com:9443; Binance geo-restriction responses; DNS misconfiguration; Binance maintenance; wrong environment URL (testnet vs prod).
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 Spot SBE WebSocket
- Binance Spot data teardown failed
- failed to connect Binance Futures market WebSocket
- failed to connect Binance Futures private WebSocket
- failed to connect Binance Futures public WebSocket
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/bd9f95f46a2c15ce.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/spot/data.rs:1581
&command_spawner,
);
}
() = cancel.cancelled() => {
log::debug!("Spot SBE WebSocket stream task cancelled");
break;
}
}
}
};
self.session_tasks
.spawn(future)
.context("failed to register Binance Spot SBE stream task")?;
}
SpotWsClient::JsonPublic(ws_client) => {
log::info!("Connecting to Binance Spot public JSON WebSocket...");
ws_client.connect().await.map_err(|e| {
log::error!("Binance Spot public JSON WebSocket connection failed: {e:?}");
anyhow::anyhow!("failed to connect Binance Spot public JSON WebSocket: {e}")
})?;
log::info!("Binance Spot public JSON WebSocket connected");
let stream = ws_client.stream();
let sender = self.data_sender.clone();
let insts = self.instruments.clone();
let ws_insts = 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 book_epoch = self.book_epoch.clone();
let http = self.http_client.clone();
let clock = self.clock;
let cancel = self.cancellation_token.clone();
let command_spawner = self
.command_tasks
.spawner()
.context("Binance Spot command task admission is closed")?;View on GitHub (pinned to 18893faf8b)