Skip to content

Telegram fails on servers without IPv6 (Node 22+ undici ignores net.setDefaultAutoSelectFamily) #10795

@yashmakhija

Description

@yashmakhija

Summary

On Node 22+, Telegram API requests fail on servers without working IPv6 connectivity. The current net.setDefaultAutoSelectFamily(false) workaround doesn't affect undici (which powers Node's built-in fetch).

Environment

  • Node.js: v22.22.0
  • OpenClaw: 2026.2.3-1
  • OS: Debian Linux (VPS without IPv6 egress)
  • Telegram lib: grammY 1.39.3

Error Logs

2026-02-07T00:35:31.152Z warn [openclaw] Non-fatal unhandled rejection (continuing): TypeError: fetch failed
    at node:internal/deps/undici/undici:14902:13
    at processTicksAndRejections (node:internal/process/task_queues:105:5)

2026-02-07T00:35:31.154Z error gateway/channels/telegram telegram setMyCommands failed: Network request for 'setMyCommands' failed!

2026-02-07T00:41:56.081Z error gateway/channels/telegram telegram sendMessage failed: Network request for 'sendMessage' failed!
2026-02-07T00:41:56.084Z error gateway/channels/telegram telegram final reply failed: HttpError: Network request for 'sendMessage' failed!

Note: The log shows telegram: autoSelectFamily=false (default-node22) — confirming OpenClaw is setting the flag, but it doesn't help.

Root Cause Analysis

  1. Node 22+ uses "Happy Eyeballs" algorithm (autoSelectFamily=true by default) which tries IPv6 first
  2. OpenClaw correctly calls net.setDefaultAutoSelectFamily(false) in applyTelegramNetworkWorkarounds()
  3. However, grammY uses Node's built-in fetch which is powered by undici
  4. Undici has its own autoSelectFamily handling in its connection logic and does not read net.getDefaultAutoSelectFamily()
  5. Result: IPv6 is still tried first → times out on servers without IPv6 → request fails

Network Diagnosis

# IPv6 - FAILS
$ curl -6 -s -o /dev/null -w "%{http_code}" --connect-timeout 5 https://api.telegram.org
000  # timeout/connection refused

# IPv4 - WORKS  
$ curl -4 -s -o /dev/null -w "%{http_code}" --connect-timeout 5 https://api.telegram.org
302  # success

# DNS returns both A and AAAA records
$ dig +short api.telegram.org A
149.154.166.110
$ dig +short api.telegram.org AAAA  
2001:67c:4e8:f004::9

Current Workaround

Adding to /etc/hosts forces IPv4:

149.154.166.110 api.telegram.org

This works but is fragile (IP could change, affects whole system).

Proposed Fix

Create a custom undici Agent with autoSelectFamily: false and pass it as the dispatcher:

const { Agent, fetch } = require('undici');

const telegramAgent = new Agent({
  connect: {
    autoSelectFamily: false
  }
});

// Wrap fetch to use our agent
const telegramFetch = (url, init) => fetch(url, { ...init, dispatcher: telegramAgent });

Tested and confirmed working:

// This succeeds on IPv6-broken servers:
const { Agent, fetch } = require('undici');
const agent = new Agent({ connect: { autoSelectFamily: false } });
fetch('https://api.telegram.org/bot.../getMe', { dispatcher: agent })
  .then(r => r.json())
  .then(console.log);
// → {"ok":false,"error_code":401,"description":"Unauthorized"}  // reaches API!

Impact

Any VPS/server without IPv6 egress (common on budget VPS, corporate networks, some cloud providers) will fail to send Telegram messages on Node 22+.

Happy to submit a PR implementing the undici Agent approach!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    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