openclaw - ✅(Solved) Fix Gateway crashes on EHOSTUNREACH from Telegram API (uncaught exception) [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74540Fetched 2026-04-30 06:23:17
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
2
Timeline (top)
closed ×2cross-referenced ×2commented ×1

The OpenClaw gateway crashes with an uncaught exception when Telegram's API becomes temporarily unreachable. A socket-level EHOSTUNREACH error from undici/lib/core/connect.js escapes the fetch fallback error handling and kills the Node process.

Error Message

11:01:13 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:13 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:20 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:24 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:30 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:34 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:41 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=EHOSTUNREACH)
11:01:41 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=EHOSTUNREACH)
11:01:41 [openclaw] Uncaught exception: Error: connect EHOSTUNREACH 149.154.167.220:443 - Local (10.0.10.40:50017)
    at internalConnect (node:net:1169:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at emitLookup (node:net:1491:9)
    at file:///opt/homebrew/lib/node_modules/openclaw/dist/ssrf-K8pX0Zi6.js:185:3
    at node:net:1468:5
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at lookupAndConnect (node:net:1467:3)
    at Socket.connect (node:net:1344:5)
    at Object.connect (node:internal/tls/wrap:1789:13)
    at connect (undici/lib/core/connect.js:70:20)

Root Cause

The fetch fallback wrapper in the Telegram transport handles higher-level HTTP errors (UND_ERR_CONNECT_TIMEOUT) but a socket-level EHOSTUNREACH from undici's connect function (ssrf-K8pX0Zi6.js:185) escapes the error boundary. Node's default behavior kills the process on uncaught exceptions.

Fix Action

Fix / Workaround

Steps to Reproduce

  1. Gateway is running with Telegram channel active
  2. Telegram API IP (149.154.167.220:443) becomes temporarily unreachable (network blip)
  3. The fetch fallback logic catches initial UND_ERR_CONNECT_TIMEOUT errors correctly — it tries alternative IPs and enables sticky IPv4-only dispatcher
  4. However, a raw EHOSTUNREACH from Node's net.connect() bubbles up outside the fetch fallback's try/catch
  5. Gateway crashes with uncaught exception

Logs

11:01:13 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:13 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:20 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:24 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:30 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:34 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:41 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=EHOSTUNREACH)
11:01:41 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=EHOSTUNREACH)
11:01:41 [openclaw] Uncaught exception: Error: connect EHOSTUNREACH 149.154.167.220:443 - Local (10.0.10.40:50017)
    at internalConnect (node:net:1169:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at emitLookup (node:net:1491:9)
    at file:///opt/homebrew/lib/node_modules/openclaw/dist/ssrf-K8pX0Zi6.js:185:3
    at node:net:1468:5
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at lookupAndConnect (node:net:1467:3)
    at Socket.connect (node:net:1344:5)
    at Object.connect (node:internal/tls/wrap:1789:13)
    at connect (undici/lib/core/connect.js:70:20)

PR fix notes

PR #74549: Fix Telegram EHOSTUNREACH gateway crash

Description (problem / solution / changelog)

Summary

  • Problem: a raw socket-level Telegram EHOSTUNREACH can reach the process uncaughtException handler and terminate the gateway even though the same transient network class is already recoverable elsewhere.
  • Why it matters: temporary Telegram API reachability blips should not kill the OpenClaw gateway.
  • What changed: shared uncaught-exception classification now treats transient network errors as benign, matching the existing unhandled-rejection behavior.
  • What did NOT change (scope boundary): no Telegram request retry policy, fetch fallback dispatcher behavior, or security-audit logic changed.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #74540
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: process-level uncaught exceptions only treated a tiny broken-pipe set as non-fatal, while transient network errors were only suppressed on the unhandled-rejection path.
  • Missing detection / guardrail: no test covered raw EHOSTUNREACH reaching the CLI uncaught-exception handler.
  • Contributing context (if known): Telegram transport already handles EHOSTUNREACH when it is delivered as a fetch rejection, but undici/socket errors can also surface as uncaught exceptions.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/infra/unhandled-rejections.test.ts, src/cli/run-main.exit.test.ts
  • Scenario the test should lock in: raw connect EHOSTUNREACH ... exceptions are logged as non-fatal and do not call process.exit(1).
  • Why this is the smallest reliable guardrail: the failure path is the shared uncaught-exception classifier and CLI handler, not Telegram fetch retry dispatch itself.
  • Existing test that already covers this (if any): Telegram fetch/network tests already cover promise-rejection fallback behavior.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Transient network uncaught exceptions are logged as non-fatal warnings instead of shutting down the CLI/gateway process.

Diagram (if applicable)

Before:
[Telegram socket EHOSTUNREACH] -> [uncaughtException] -> [process exit]

After:
[Telegram socket EHOSTUNREACH] -> [transient network classification] -> [warn and continue]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: Windows local checkout
  • Runtime/container: Node 22 via repo scripts
  • Model/provider: N/A
  • Integration/channel (if any): Telegram network failure path
  • Relevant config (redacted): N/A

Steps

  1. Simulate a raw uncaught EHOSTUNREACH error.
  2. Pass it through isBenignUncaughtExceptionError() and the CLI uncaught-exception handler.
  3. Verify the handler warns and does not exit.

Expected

  • Transient Telegram host-unreachable failures do not terminate the gateway process.

Actual

  • Fixed by this PR.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • pnpm test src/infra/unhandled-rejections.test.ts -t "treats raw transient network uncaught exceptions as benign" -- --reporter=verbose
    • pnpm test src/infra/unhandled-rejections.test.ts src/cli/run-main.exit.test.ts -- --reporter=verbose
    • pnpm test extensions/telegram/src/fetch.test.ts extensions/telegram/src/network-errors.test.ts -- --reporter=verbose
    • pnpm check:changed
    • git diff --check
  • Edge cases checked: generic errors still are not benign; transient SQLite remains rejected for uncaught-exception suppression; Telegram fetch fallback tests still pass.
  • What you did not verify: live Telegram outage against the real Bot API.

Note: pnpm test:changed was run and failed in three unrelated Windows baseline cases. I stashed this PR patch and reran the exact failing files on the unmodified base; the same failures reproduced:

  • src/crestodian/rescue-message.test.ts expects /tmp/work but receives C:\tmp\work.
  • src/crestodian/operations.test.ts expects /tmp/work but receives C:\tmp\work.
  • src/security/audit-sandbox-docker-config.test.ts misclassifies a Windows short home path as non-absolute.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: continuing after a transient uncaught exception may leave a single integration operation failed.
    • Mitigation: this matches the existing unhandled-rejection policy for transient network errors and keeps fatal/config errors exiting as before.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/telegram/src/monitor.test.ts (modified, +86/-19)
  • extensions/telegram/src/monitor.ts (modified, +22/-12)
  • src/cli/run-main.exit.test.ts (modified, +5/-3)
  • src/infra/unhandled-rejections.test.ts (modified, +9/-1)
  • src/infra/unhandled-rejections.ts (modified, +33/-0)

Code Example

11:01:13 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:13 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:20 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:24 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:30 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:34 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:41 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=EHOSTUNREACH)
11:01:41 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=EHOSTUNREACH)
11:01:41 [openclaw] Uncaught exception: Error: connect EHOSTUNREACH 149.154.167.220:443 - Local (10.0.10.40:50017)
    at internalConnect (node:net:1169:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at emitLookup (node:net:1491:9)
    at file:///opt/homebrew/lib/node_modules/openclaw/dist/ssrf-K8pX0Zi6.js:185:3
    at node:net:1468:5
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at lookupAndConnect (node:net:1467:3)
    at Socket.connect (node:net:1344:5)
    at Object.connect (node:internal/tls/wrap:1789:13)
    at connect (undici/lib/core/connect.js:70:20)
RAW_BUFFERClick to expand / collapse

Bug Report

Summary

The OpenClaw gateway crashes with an uncaught exception when Telegram's API becomes temporarily unreachable. A socket-level EHOSTUNREACH error from undici/lib/core/connect.js escapes the fetch fallback error handling and kills the Node process.

Environment

  • OpenClaw: 2026.4.26 (da6bdffc3d96)
  • Node: v25.9.0
  • OS: macOS (Darwin arm64)
  • Channel: Telegram

Steps to Reproduce

  1. Gateway is running with Telegram channel active
  2. Telegram API IP (149.154.167.220:443) becomes temporarily unreachable (network blip)
  3. The fetch fallback logic catches initial UND_ERR_CONNECT_TIMEOUT errors correctly — it tries alternative IPs and enables sticky IPv4-only dispatcher
  4. However, a raw EHOSTUNREACH from Node's net.connect() bubbles up outside the fetch fallback's try/catch
  5. Gateway crashes with uncaught exception

Logs

11:01:13 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:13 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:20 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:24 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:30 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:34 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=UND_ERR_CONNECT_TIMEOUT)
11:01:41 [telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=EHOSTUNREACH)
11:01:41 [telegram] fetch fallback: DNS-resolved IP unreachable; trying alternative Telegram API IP (codes=EHOSTUNREACH)
11:01:41 [openclaw] Uncaught exception: Error: connect EHOSTUNREACH 149.154.167.220:443 - Local (10.0.10.40:50017)
    at internalConnect (node:net:1169:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at emitLookup (node:net:1491:9)
    at file:///opt/homebrew/lib/node_modules/openclaw/dist/ssrf-K8pX0Zi6.js:185:3
    at node:net:1468:5
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:473:12)
    at lookupAndConnect (node:net:1467:3)
    at Socket.connect (node:net:1344:5)
    at Object.connect (node:internal/tls/wrap:1789:13)
    at connect (undici/lib/core/connect.js:70:20)

Root Cause Analysis

The fetch fallback wrapper in the Telegram transport handles higher-level HTTP errors (UND_ERR_CONNECT_TIMEOUT) but a socket-level EHOSTUNREACH from undici's connect function (ssrf-K8pX0Zi6.js:185) escapes the error boundary. Node's default behavior kills the process on uncaught exceptions.

Expected Behavior

  • Transient network failures to Telegram's API should be caught and retried with exponential backoff
  • The gateway should remain running and reconnect when the network recovers
  • The fetch fallback should handle EHOSTUNREACH the same way it handles UND_ERR_CONNECT_TIMEOUT

Stability Bundle

Written to: ~/.openclaw/logs/stability/openclaw-stability-2026-04-29T18-01-41-234Z-33028-uncaught_exception.json

Additional Context

The session was also stuck in processing state for 891s before the crash, which may have contributed to the timing (multiple queued messages attempting delivery simultaneously when the network went down).

extent analysis

TL;DR

The OpenClaw gateway can be fixed by catching and handling the EHOSTUNREACH error in the fetch fallback logic to prevent the process from crashing.

Guidance

  • Review the undici/lib/core/connect.js file to understand how the EHOSTUNREACH error is being thrown and how it can be caught.
  • Modify the fetch fallback wrapper in the Telegram transport to catch and handle EHOSTUNREACH errors in the same way as UND_ERR_CONNECT_TIMEOUT errors.
  • Implement exponential backoff for retrying connections to Telegram's API to handle transient network failures.
  • Consider adding additional logging to track the occurrence of EHOSTUNREACH errors and the effectiveness of the modified fetch fallback logic.

Example

try {
  // existing fetch fallback logic
} catch (error) {
  if (error.code === 'EHOSTUNREACH') {
    // handle EHOSTUNREACH error in the same way as UND_ERR_CONNECT_TIMEOUT
    // enable sticky IPv4-only dispatcher and retry connection
  } else {
    // handle other errors
  }
}

Notes

The provided logs and root cause analysis suggest that the issue is specific to the EHOSTUNREACH error and the fetch fallback logic. However, the session being stuck in processing state for an extended period may have contributed to the timing of the crash.

Recommendation

Apply a workaround by modifying the fetch fallback logic to catch and handle EHOSTUNREACH errors. This will prevent the process from crashing and allow the gateway to remain running and reconnect when the network recovers.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Gateway crashes on EHOSTUNREACH from Telegram API (uncaught exception) [1 pull requests, 1 comments, 2 participants]