-
-
Notifications
You must be signed in to change notification settings - Fork 69.4k
Telegram channel broken after upgrading to 2026.3.x — undici bypasses macOS TUN/VPN #33013
Description
Telegram channel broken after upgrading to 2026.3.x — undici bypasses macOS TUN/VPN
Environment
- OpenClaw version: 2026.3.2 (regression; works fine on 2026.2.26)
- OS: macOS 15.5 (arm64, Apple Silicon)
- Node.js: v24.11.1
- VPN: Outline VPN (TUN mode — captures all system traffic at the network interface level)
- Telegram bot library: grammy (via undici fetch)
- Install method: npm (
npm install -g openclaw) - Gateway mode: LaunchAgent (
ai.openclaw.gateway)
Summary
After upgrading from 2026.2.26 to 2026.3.x, the Telegram channel fails to connect with repeated Network request for '<method>' failed! errors. All Telegram Bot API calls (deleteWebhook, deleteMyCommands, setMyCommands, polling) fail immediately on gateway startup.
Rolling back to 2026.2.26 resolves the issue completely.
Symptoms
On gateway startup, the following errors repeat in a loop every ~30 seconds:
error gateway/channels/telegram telegram deleteWebhook failed: Network request for 'deleteWebhook' failed!
error gateway/channels/telegram Telegram webhook cleanup failed: Network request for 'deleteWebhook' failed!; retrying in 7.63s.
error gateway/channels/telegram telegram deleteMyCommands failed: Network request for 'deleteMyCommands' failed!
error gateway/channels/telegram telegram setMyCommands failed: Network request for 'setMyCommands' failed!
error gateway/channels/telegram Telegram command sync failed: HttpError: Network request for 'setMyCommands' failed!
The Telegram channel shows status: WARN │ failed (unknown) - This operation was aborted
Root Cause Analysis
Through debugging, I identified that the 2026.3.x Telegram module switched its HTTP client from Node.js native fetch to undici (import { fetch } from "undici"), specifically in:
dist/proxy-fetch-DrI0Gh6p.js— usesundici.ProxyAgentandundici.EnvHttpProxyAgentdist/send-BfbOwTR-.js—resolveTelegramFetch()resolves to undici-based fetch
undici maintains its own network stack and DNS resolution, which bypasses macOS's TUN-mode VPN tunnel. This means:
| Client | Uses system network stack | Goes through TUN VPN | Result |
|---|---|---|---|
curl |
✅ Yes | ✅ Yes | ✅ HTTP 200 |
Node.js native https.get |
✅ Yes | ✅ Yes | ✅ HTTP 200 |
Node.js native fetch |
✅ Yes | ✅ Yes | ✅ HTTP 200 |
undici fetch |
❌ Own stack | ❌ Bypasses TUN | ❌ Network request failed |
Verification
From the same terminal session where openclaw gateway was running:
# Native curl — works
$ curl -sS https://api.telegram.org/bot<token>/getMe
{"ok":true,"result":{"id":...,"is_bot":true,...}}
# Node.js native https — works
$ node -e "require('https').get('https://api.telegram.org/bot<token>/getMe', r => { let d=''; r.on('data',c=>d+=c); r.on('end',()=>console.log(d)) })"
{"ok":true,"result":{"id":...,"is_bot":true,...}}
# But OpenClaw gateway (using undici) — fails
error gateway/channels/telegram telegram deleteWebhook failed: Network request for 'deleteWebhook' failed!Workaround
Option 1: Rollback to 2026.2.26 (confirmed working)
npm install -g [email protected]
openclaw gateway restartOption 2: Local HTTP CONNECT proxy (forces undici through system network)
Create a minimal local proxy that uses Node.js native net.connect (which respects TUN):
// ~/.openclaw/telegram-proxy.mjs
import { createServer } from 'node:http';
import { connect } from 'node:net';
const PORT = 18800;
const server = createServer();
server.on('connect', (req, clientSocket, head) => {
const [host, port] = req.url.split(':');
const serverSocket = connect(parseInt(port) || 443, host, () => {
clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
if (head.length) serverSocket.write(head);
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
});
serverSocket.on('error', () => clientSocket.destroy());
clientSocket.on('error', () => serverSocket.destroy());
});
server.listen(PORT, '127.0.0.1');Then configure in openclaw.json:
{
"channels": {
"telegram": {
"proxy": "http://127.0.0.1:18800"
}
}
}Expected Behavior
The Telegram channel should work with TUN-mode VPNs (Outline, WireGuard, etc.) without requiring an explicit proxy configuration, as it did in 2026.2.26.
Suggested Fix
Consider one of the following:
-
Use Node.js native
fetch(available since Node 18+) instead of undici'sfetchfor Telegram API calls. Native fetch respects the OS network stack and TUN routing. -
Fall back to native fetch when undici fails — detect the "Network request failed" error pattern and automatically retry with
globalThis.fetch. -
Respect
NODE_USE_SYSTEM_CAand system network settings — if the environment indicates system-level networking should be used, prefer the native stack. -
Document the
channels.telegram.proxyworkaround for users in restricted network environments.
Affected Versions
- Broken: 2026.3.1, 2026.3.2
- Working: 2026.2.26 and earlier
Additional Context
- This affects any user behind a TUN-mode VPN (common in China, corporate networks, etc.)
- The issue is not specific to Telegram — any OpenClaw module that switched to undici may have the same problem
- macOS LaunchAgent-started gateway processes are especially affected since they don't inherit user shell proxy environment variables