vectordotdev/vector · error
Pong not received in time
Error message
Pong not received in time
What it means
Runtime error from the WebSocket sink's connection supervision in src/sinks/websocket/sink.rs. The sink sends pings and records the last pong time; `check_received_pong_time` compares `last_pong.elapsed()` against the configured `ping_timeout` and, when exceeded, returns a tungstenite `Error::Io` with kind `TimedOut` ("Pong not received in time"). This tears down the connection and triggers the sink's reconnect-with-backoff loop.
Source
Thrown at src/sinks/websocket/sink.rs:68
ping_timeout: config.common.ping_timeout,
})
}
async fn create_sink_and_stream(
&self,
) -> (
impl Sink<Message, Error = TungsteniteError> + use<>,
impl Stream<Item = Result<Message, TungsteniteError>> + use<>,
) {
let ws_stream = self.connector.connect_backoff().await;
ws_stream.split()
}
fn check_received_pong_time(&self, last_pong: Instant) -> Result<(), TungsteniteError> {
if let Some(ping_timeout) = self.ping_timeout
&& last_pong.elapsed() > Duration::from_secs(ping_timeout.into())
{
return Err(TungsteniteError::Io(io::Error::new(
io::ErrorKind::TimedOut,
"Pong not received in time",
)));
}
Ok(())
}
async fn handle_events<I, WS, O>(
&mut self,
input: &mut I,
ws_stream: &mut WS,
ws_sink: &mut O,
) -> Result<(), ()>
where
I: Stream<Item = Event> + Unpin,
WS: Stream<Item = Result<Message, TungsteniteError>> + Unpin,
O: Sink<Message, Error = TungsteniteError> + Unpin,View on GitHub (pinned to 3708c39b12)
Solutions
- Increase `ping_timeout` on the WebSocket sink so legitimate latency can't trip it
- Confirm the server answers RFC 6455 pings (most frameworks do automatically; custom servers may not)
- Check proxies/LBs between Vector and the server for idle-timeout kills or filtered ping/pong frames
- Rely on the built-in reconnect: after this error the sink re-establishes the connection with backoff, so a one-off blip self-heals
Example fix
# before [sinks.out] type = "websocket" uri = "wss://example.com/ws" ping_timeout = 5 # too tight, trips on normal latency # after [sinks.out] type = "websocket" uri = "wss://example.com/ws" ping_timeout = 30
Defensive patterns
Strategy: retry
Validate before calling
# Smoke-test that the endpoint answers pings before shipping # (any RFC 6455 client with ping/pong enabled; a stalled pong = server-side problem)
Try / catch
loop {
match run_sink_session(&mut input).await {
Err(TungsteniteError::Io(ref e)) if e.kind() == std::io::ErrorKind::TimedOut => {
// pong timeout: reconnect with backoff (the sink's built-in behavior)
backoff.wait().await;
}
Err(e) => return Err(e),
Ok(()) => break,
}
} Prevention
- Set ping_timeout comfortably above worst-case RTT plus server pong latency
- Confirm the server and any proxies forward WebSocket ping/pong frames
- Rely on the sink's reconnect-with-backoff; alert on repeated timeouts, not the first one
When it happens
Trigger: The remote WebSocket endpoint stops answering protocol-level pings (RFC 6455 pong frames) for longer than `ping_timeout` seconds: dead/unresponsive server, half-open TCP connection, silent network drop, or a proxy stripping ping/pong frames.
Common situations: WebSocket servers that don't implement pong replies; intermediaries (nginx, cloud LBs) with idle timeouts closing the connection quietly; mobile/flaky networks where the connection dies without a FIN; `ping_timeout` set lower than real round-trip times.
Related errors
- BrokenPipe
- poll_ready must be called first
- No timeout is configured for this source.
- Encountered a connection-time error during runtime: {:?}
- path and query should never fail to parse
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/c0f80142ebc9ae16.
Report an issue: GitHub.