vectordotdev/vector · error · TungsteniteError

Pong not received in time

Error message

Pong not received in time

What it means

The WebSocket sink optionally requires periodic Pong frames from the server when ping_timeout is configured. check_received_pong_time compares the elapsed time since the last received pong against ping_timeout; if exceeded, it returns a TungsteniteError wrapping an io::Error with ErrorKind::TimedOut and message 'Pong not received in time'. This indicates the server is unresponsive to keep-alive pings and the connection is treated as dead.

Solutions

  1. Increase ping_timeout in the sink configuration to accommodate server/network latency.
  2. Verify the server actually responds to WebSocket ping frames (many services only answer protocol-level pings irregularly).
  3. Ensure proxies/load balancers are configured with idle timeouts longer than ping_timeout.
  4. Rely on Vector's retry behavior; the sink reconnects after this error by design.

Example fix

// before
[sinks.my_ws]
  type = "websocket"
  ping_timeout = 5
// after
[sinks.my_ws]
  type = "websocket"
  ping_timeout = 60
Defensive patterns

Strategy: retry

Try / catch

// sink reconnects automatically; capture in logs
error!(message = "websocket pong timeout", error = ?err); // rely on Vector retry/backoff

Prevention

When it happens

Trigger: ping_timeout is set on the websocket sink, no pong frame has been received for longer than ping_timeout seconds, and the sink's health loop calls check_received_pong_time.

Common situations: Server does not answer ping frames; intermediary proxies/load balancers drop idle WebSocket connections; ping_timeout configured too aggressively for the server's response latency; network partitions.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/c0f80142ebc9ae16. Report an issue: GitHub.

Appendix: source

Thrown at src/sinks/websocket/sink.rs:70

            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 bdb87aeaa4)