Skip to content

Telegram channel health-monitor restart triggers full gateway EADDRINUSE loop (same class as #22169) #68153

Description

@shinny77

Bug

The gateway/health-monitor detects the Telegram channel as "stuck" during quiet periods (no messages for 30+ minutes) and attempts a restart. The restart path triggers a full gateway bind attempt on the main WebSocket port (18789), which fails with EADDRINUSE because the gateway already owns the port. This produces ~67 error log lines per cycle, repeating every 30 minutes indefinitely.

Same class as #22169, #24522, #25527

The MS Teams EADDRINUSE restart loop bugs were caused by the same pattern: channel restart cascading into a full gateway bind attempt. Those were fixed for MS Teams but the same bug exists in the Telegram channel restart path.

Reproduction

  1. Run OpenClaw gateway with Telegram channel enabled
  2. Wait 30+ minutes with no incoming Telegram messages
  3. Health monitor triggers: [telegram:default] health-monitor: restarting (reason: stuck)
  4. Restart attempts to bind port 18789, fails with EADDRINUSE
  5. Cycle repeats every 30 minutes

Evidence

  • Version: 2026.3.1
  • Health monitor config: interval 300s (5 min), grace 60s
  • Stale event threshold: 30 min (DEFAULT_STALE_EVENT_THRESHOLD_MS = 30 * 60000)
  • Restart frequency: every ~30 min during quiet periods
  • Error count: 2204 EADDRINUSE errors in 27 hours, 33 restart cycles
  • Gateway is fully functional throughout - this is log spam, not a service outage

Log pattern per cycle

[telegram:default] health-monitor: restarting (reason: stuck)
[default] starting provider (@anika_openclaw_bot)
canvas host mounted at http://0.0.0.0:18789
Gateway is binding to a non-loopback address
Gateway failed to start: another gateway instance is already listening on ws://0.0.0.0:18789
Port 18789 is already in use.
- pid NNNN openclaw: openclaw-gateway (*:18789)

Root cause

channel-health-monitor.ts line ~1595: the isChannelHealthy() function treats a Telegram channel with no events for 30 min as unhealthy. For Telegram (long-polling), quiet periods with no messages are normal - unlike Slack WebSocket where a stale socket genuinely indicates a problem.

The restart calls channelManager.stopChannel() then channelManager.startChannel(). The startChannel path for Telegram appears to cascade into a full gateway initialization that attempts to bind the main port.

Suggested fixes

  1. Channel-specific stale thresholds: Telegram long-polling does not have the same stale-socket failure mode as Slack WebSocket. Either exempt Telegram from stale-event detection or use a much higher threshold (4h+)
  2. Port-ownership guard: Before attempting to bind during restart, check if the current process already owns the port. If so, skip the bind
  3. Channel-only restart: The restart path should reinitialise only the channel provider, not the full gateway

Workaround

gateway.channelHealthCheckMinutes: 0 in openclaw.json disables the health monitor entirely. This works but removes the safety net for genuinely stuck channels.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions