hcengineering/platform · warning

WS-server not responding to ping, closing connection

Error message

WS-server not responding to ping, closing connection

What it means

In startPing, the client sends pings on an interval and arms a PING_TIMEOUT_MS timer; if the socket is not OPEN when the timeout fires, it concludes the server never answered the ping, warns 'WS-server not responding to ping, closing connection', stops the ping interval, and closes the socket with WS_CLOSE_NORMAL. This is the client's keepalive/liveness mechanism detecting a dead or stalled connection.

Source

Thrown at packages/hulypulse-client/src/client.ts:235

      this.send({ type: 'sub', key }).catch((error) => {
        console.error(`Resubscription failed for key=${key}:`, error)
        // throw new Error(`Resubscription failed for key=${key}: ${error.message ?? error}`)
      })
    }
  }

  private startPing (): void {
    this.stopPing()
    this.pingInterval = setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send('ping')
      }
      if (this.pingTimeout !== undefined) {
        clearTimeout(this.pingTimeout)
      }
      this.pingTimeout = setTimeout(() => {
        if (this.ws?.readyState !== WebSocket.OPEN) {
          console.warn('WS-server not responding to ping, closing connection')
          clearInterval(this.pingInterval)
          this.ws?.close(WS_CLOSE_NORMAL)
        }
      }, this.PING_TIMEOUT_MS)
    }, this.PING_INTERVAL_MS)
  }

  private stopPing (): void {
    if (this.pingInterval !== undefined) {
      clearInterval(this.pingInterval)
      this.pingInterval = undefined
    }
    if (this.pingTimeout !== undefined) {
      clearTimeout(this.pingTimeout)
      this.pingTimeout = undefined
    }
  }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check server availability/logs around the disconnect time - the server likely died or restarted.
  2. Reduce network instability: keep-alives at the TCP/proxy level, avoid long idle periods behind NAT/load balancers.
  3. After close, reconnect with exponential backoff (the client should resubscribe state on reconnect).
  4. Tune PING_INTERVAL_MS / PING_TIMEOUT_MS if legitimate slow networks cause false positives.

Example fix

// before
this.pingTimeout = setTimeout(() => {
  if (this.ws?.readyState !== WebSocket.OPEN) {
    console.warn('WS-server not responding to ping, closing connection')
    clearInterval(this.pingInterval)
    this.ws?.close(WS_CLOSE_NORMAL)
  }
}, this.PING_TIMEOUT_MS)
// after
this.pingTimeout = setTimeout(() => {
  if (this.ws?.readyState !== WebSocket.OPEN) {
    console.warn('WS-server not responding to ping, closing connection')
    clearInterval(this.pingInterval)
    this.ws?.close(WS_CLOSE_NORMAL)
    this.scheduleReconnect() // reconnect with backoff instead of staying closed
  }
}, this.PING_TIMEOUT_MS)
Defensive patterns

Strategy: retry

Validate before calling

// Before relying on a connection, check readiness
if (client.ws?.readyState !== WebSocket.OPEN) {
  await client.reconnect()
}

Type guard

function isOpen (ws: WebSocket | null | undefined): ws is WebSocket {
  return ws != null && ws.readyState === WebSocket.OPEN
}

Try / catch

try {
  await client.send(msg)
} catch (e) {
  await backoffReconnect(client) // connection likely dead after ping timeout
}

Prevention

When it happens

Trigger: No pong (or no expected ping response) is received within PING_TIMEOUT_MS after a ping, or the WebSocket has left the OPEN state between pings.

Common situations: Server restart or crash; network blackholes (laptop sleep, NAT timeout, mobile network switch); overloaded WS server that stops responding to pings; firewall silently dropping idle connections.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/79fe806d0953dfc0. Report an issue: GitHub.