Skip to content

WhatsApp: Persistent 408 session timeout loop — WebSocket keepalive not preventing server-side idle disconnect #63410

@legonhilltech-jpg

Description

@legonhilltech-jpg

Summary

WhatsApp gateway disconnects with status 408 every ~15-17 minutes in a persistent, metronomic loop. The connection auto-reconnects successfully each time, but the loop never stops and causes message delivery failures during disconnect windows.

Environment

  • OpenClaw version: 2026.4.8 (9ece252)
  • macOS (arm64), Node v25.8.2
  • Two WhatsApp accounts on the same gateway (default + secondary)
  • Multi-Device protocol (Baileys)

Observed Behavior

The gateway drops with status 408 every ~15-17 minutes, consistently:

2026-04-08T01:45 | first drop
2026-04-08T02:01 | +16 min
2026-04-08T02:18 | +16 min
2026-04-08T02:34 | +15 min
2026-04-08T02:50 | +16 min
... (60+ drops over 17 hours, same interval)

Both accounts drop simultaneously, suggesting this is a server-side session-level idle timeout, not a network issue.

What Was Tried

  1. Gateway restarts — clears the loop temporarily, but it resumes within ~24 minutes.
  2. Reduced heartbeat interval — changed agents.defaults.heartbeat.every from 30m to 10m with a lightweight model (gemini-2.5-flash-lite). This generates WhatsApp traffic via the heartbeat reply. Did NOT prevent the 408 drops — they continued at the same ~16 min interval.
  3. web.heartbeatSeconds — confirmed the plugin is already sending WebSocket-level pings at 60s intervals. These pings are not preventing the server-side session timeout.

Root Cause Hypothesis

The WhatsApp Multi-Device protocol has a server-side session idle timer of approximately 15-16 minutes. If the OpenClaw/Baileys WebSocket layer is not sending a protocol-level keepalive that WhatsApp's servers recognize as "session activity" (distinct from a TCP-level ping), the server recycles the session with a 408.

The internal web-heartbeat module (logging messagesHandled, uptimeMs, lastInboundAt) appears to be a monitoring-only loop that does not transmit any data to WhatsApp's servers.

Suggested Fix

The Baileys WhatsApp plugin should send a protocol-level keepalive (e.g., a no-op IQ stanza or presence update) to WhatsApp's servers at an interval shorter than the server's idle timeout (~10-12 minutes). This is separate from the TCP WebSocket ping and must be a WhatsApp application-layer message that resets the server's session idle timer.

Impact

  • Auto-reconnect handles the drop cleanly (no data loss in most cases)
  • Messages sent during the ~2-4 second disconnect window fail with forbidden (outbound) or are silently dropped (inbound)
  • 60+ API calls burned over 17 hours due to reconnect cycles
  • Agents relying on WhatsApp for proactive alerts cannot reliably reach users during disconnect windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions