nautechsystems/nautilus_trader · warning · anyhow::Error
Failed to send pong: {e}
Error message
Failed to send pong: {e} What it means
OKX sends text `ping` frames on its WebSocket; the handler responds with a pong via the sink. If the send fails (socket closed, backpressure, or send channel dropped), the handler logs a warning and returns this error, which typically triggers reconnect logic because the connection is no longer healthy.
Source
Thrown at crates/adapters/okx/src/websocket/handler.rs:232
rate_limit_keys: Option<&[Ustr]>,
) -> Result<(), OKXWsError> {
let client = self.inner.as_ref().ok_or(OKXWsError::NoActiveClient)?;
let connection_epoch = client.connection_epoch();
client
.send_text_on_connection(payload, rate_limit_keys, connection_epoch)
.await
.map_err(OKXWsError::TransportSend)
}
pub(super) async fn send_pong(&self) -> anyhow::Result<()> {
match self.send_on_connection(TEXT_PONG.to_string(), None).await {
Ok(()) => {
log::trace!("Sent pong response to OKX text ping");
Ok(())
}
Err(e) => {
log::warn!("Failed to send pong: error={e}");
Err(anyhow::anyhow!("Failed to send pong: {e}"))
}
}
}
pub(super) async fn next(&mut self) -> Option<OKXWsMessage> {
if let Some(message) = self.pending_messages.pop_front() {
return Some(message);
}
let mut poll_raw_next = false;
loop {
if self.signal.load(Ordering::Acquire) {
log::debug!("Stop signal received");
return None;
}
tokio::select! {View on GitHub (pinned to 18893faf8b)
Solutions
- Let the error propagate to the reconnect loop and re-establish the connection — the socket is already unusable.
- Check network/proxy idle timeouts and enable keep-alive so pings can be answered in time.
- Verify the write half of the WebSocket is still shared/alive when the handler runs.
Defensive patterns
Strategy: try-catch
Try / catch
// treat as connection-lost: trigger reconnect
if let Err(e) = handler_result {
log::warn!("ws unhealthy: {e}; reconnecting");
reconnect_with_backoff().await;
} Prevention
- Configure proxy/firewall idle timeouts longer than OKX's ping interval.
- Ensure the network is stable; pongs failing implies the socket is already broken.
- Monitor logs for repeated pong failures as an early disconnect signal.
When it happens
Trigger: OKX sends a text ping while the underlying WebSocket is closed/broken or the send sink is unavailable, so `send(...)` returns Err in `send_pong`.
Common situations: Network interruption mid-session; server closed the connection while a queued ping was being answered; proxy or firewall idle-timeout dropped the socket.
Related errors
- Invalid `BarSpecification` for channel, was {bar_spec}
- errors.join("; ")
- Timeout waiting for account {account_id} to be registered af
- `api_key`, `api_secret`, `api_passphrase` credentials must b
- Cannot connect while previous WebSocket handler task is stil
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7e70740258f9d0de.
Report an issue: GitHub.