openclaw - 💡(How to fix) Fix SSRF guard pinned DNS dispatcher causes model fetch timeouts when autoSelectFamily is enabled

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…

Starting from OpenClaw 2026.5.12, the SSRF guard's pinned DNS dispatcher conflicts with Node.js's autoSelectFamily (Happy Eyeballs / RFC 8305), causing model fetch requests to time out after 120 seconds. This makes the gateway completely unresponsive to messages on affected providers.

Error Message

const undici = require('undici');

const pinnedLookup = (hostname, options, callback) => { // Simplified: always return IPv4 only callback(null, '104.21.8.112', 4); };

// This FAILS with "TypeError: Invalid IP address: undefined" const agent = new undici.Agent({ allowH2: false, connect: { lookup: pinnedLookup, autoSelectFamily: true, autoSelectFamilyAttemptTimeout: 300, }, });

// This WORKS const agent = new undici.Agent({ allowH2: false, connect: { lookup: pinnedLookup, autoSelectFamily: false, }, });

Root Cause

The SSRF guard (introduced in 5.12) creates a pinned DNS dispatcher using undici's Agent with a custom lookup function and autoSelectFamily: true. This combination fails:

Fix Action

Workaround

Setting NODE_OPTIONS=--no-network-family-autoselection in the gateway systemd service disables Happy Eyeballs, which allows the pinned lookup to work without interference. However, this is a partial workaround because:

  • It forces all connections through the first resolved address (IPv4 when dedupeAndPreferIpv4 is used)
  • For environments where IPv6 is preferred or required (e.g., Telegram in regions with IPv4 blocking), this degrades connectivity
  • The Telegram module loses its ability to try IPv6 when IPv4 fails

Code Example

[model-fetch] start provider=hydragpt api=openai-completions model=glm-5p1 method=POST url=https://hydragpt.ru/v1/chat/completions timeoutMs=120000 proxy=none policy=custom
... 120 seconds pass ...
[fetch-timeout] fetch timeout after 120000ms operation=fetchWithSsrFGuard url=https://hydragpt.ru/v1/chat/completions
[model-fetch] error provider=hydragpt api=openai-completions model=glm-5p1 elapsedMs=120102 name=TimeoutError message=request timed out
Embedded agent failed before reply: LLM idle timeout (120s): no response from model

---

// DNS returns IPv6 first (Node.js default):
// [IPv6: 2606:4700:3037::6815:870, IPv6: 2606:4700:3034::ac43:9d56, IPv4: 104.21.8.112, IPv4: 172.67.157.86]

// dedupeAndPreferIpv4 reorders to:
// [IPv4: 104.21.8.112, IPv4: 172.67.157.86, IPv6: 2606:4700:3037::6815:870, IPv6: 2606:4700:3034::ac43:9d56]

---

const undici = require('undici');

const pinnedLookup = (hostname, options, callback) => {
  // Simplified: always return IPv4 only
  callback(null, '104.21.8.112', 4);
};

// This FAILS with "TypeError: Invalid IP address: undefined"
const agent = new undici.Agent({
  allowH2: false,
  connect: {
    lookup: pinnedLookup,
    autoSelectFamily: true,
    autoSelectFamilyAttemptTimeout: 300,
  },
});

// This WORKS
const agent = new undici.Agent({
  allowH2: false,
  connect: {
    lookup: pinnedLookup,
    autoSelectFamily: false,
  },
});

---

[telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)
RAW_BUFFERClick to expand / collapse

Summary

Starting from OpenClaw 2026.5.12, the SSRF guard's pinned DNS dispatcher conflicts with Node.js's autoSelectFamily (Happy Eyeballs / RFC 8305), causing model fetch requests to time out after 120 seconds. This makes the gateway completely unresponsive to messages on affected providers.

Environment

  • OpenClaw versions affected: 2026.5.12, 5.18, 5.22, 5.26, 5.27
  • OpenClaw version working: 2026.5.7 (pre-SSRF guard)
  • Node.js: v24.15.0
  • OS: Ubuntu 25.04, Linux 6.14.0-37-generic (x64)
  • Provider: Custom OpenAI-compatible (openai-completions API), baseUrl https://hydragpt.ru/v1
  • IPv6: Available on host, IPv6 route present via SLAAC

Problem

After upgrading from 5.7 to any version ≥5.12, the gateway cannot reach the model provider. Every model fetch request times out at exactly 120 seconds:

[model-fetch] start provider=hydragpt api=openai-completions model=glm-5p1 method=POST url=https://hydragpt.ru/v1/chat/completions timeoutMs=120000 proxy=none policy=custom
... 120 seconds pass ...
[fetch-timeout] fetch timeout after 120000ms operation=fetchWithSsrFGuard url=https://hydragpt.ru/v1/chat/completions
[model-fetch] error provider=hydragpt api=openai-completions model=glm-5p1 elapsedMs=120102 name=TimeoutError message=request timed out
Embedded agent failed before reply: LLM idle timeout (120s): no response from model

Key observation: The provider's request counter on their side does NOT increment — the request never reaches the server at all. The TCP connection is never established.

CLI inference works fine: openclaw infer model run --prompt "hello" --model hydragpt/glm-5p1 returns a response instantly on the same machine and same version. Only the gateway is affected.

Root Cause Analysis

The SSRF guard (introduced in 5.12) creates a pinned DNS dispatcher using undici's Agent with a custom lookup function and autoSelectFamily: true. This combination fails:

1. dedupeAndPreferIpv4 reorders addresses

In ssrf-B5bGsnx-.js, resolvePinnedHostnameWithPolicy calls dedupeAndPreferIpv4 which puts IPv4 addresses before IPv6:

// DNS returns IPv6 first (Node.js default):
// [IPv6: 2606:4700:3037::6815:870, IPv6: 2606:4700:3034::ac43:9d56, IPv4: 104.21.8.112, IPv4: 172.67.157.86]

// dedupeAndPreferIpv4 reorders to:
// [IPv4: 104.21.8.112, IPv4: 172.67.157.86, IPv6: 2606:4700:3037::6815:870, IPv6: 2606:4700:3034::ac43:9d56]

2. Pinned lookup + autoSelectFamily = broken

In undici-runtime-BdHHFzbs.js, withHttp1OnlyDispatcherOptions sets autoSelectFamily from the Node.js system default (true on Node 20+). When undici's autoSelectFamily mechanism calls the pinned lookup with {all: true}, the interaction breaks:

Reproduction:

const undici = require('undici');

const pinnedLookup = (hostname, options, callback) => {
  // Simplified: always return IPv4 only
  callback(null, '104.21.8.112', 4);
};

// This FAILS with "TypeError: Invalid IP address: undefined"
const agent = new undici.Agent({
  allowH2: false,
  connect: {
    lookup: pinnedLookup,
    autoSelectFamily: true,
    autoSelectFamilyAttemptTimeout: 300,
  },
});

// This WORKS
const agent = new undici.Agent({
  allowH2: false,
  connect: {
    lookup: pinnedLookup,
    autoSelectFamily: false,
  },
});

When the pinned lookup returns a single (address, family) result instead of an array for {all: true}, or when autoSelectFamily tries to perform Happy Eyeballs with a lookup that doesn't properly support the dual-family resolution pattern, the connection attempt produces Invalid IP address: undefined or simply hangs until timeout.

3. Telegram module has a workaround, model fetch does not

The Telegram subsystem has its own IPv6 fallback mechanism:

[telegram] fetch fallback: enabling sticky IPv4-only dispatcher (codes=UND_ERR_CONNECT_TIMEOUT)

The model fetch path through buildGuardedModelFetchfetchWithSsrFGuard has no such fallback — it simply hangs until the 120s timeout.

4. Why CLI inference works

openclaw infer model run uses a different code path that does not go through the gateway's SSRF-guarded fetch pipeline, so it connects successfully.

Workaround

Setting NODE_OPTIONS=--no-network-family-autoselection in the gateway systemd service disables Happy Eyeballs, which allows the pinned lookup to work without interference. However, this is a partial workaround because:

  • It forces all connections through the first resolved address (IPv4 when dedupeAndPreferIpv4 is used)
  • For environments where IPv6 is preferred or required (e.g., Telegram in regions with IPv4 blocking), this degrades connectivity
  • The Telegram module loses its ability to try IPv6 when IPv4 fails

Suggested Fix

  1. Short-term: The model fetch path should have the same IPv4/IPv6 fallback mechanism that the Telegram module already implements. If the primary connection attempt fails with a timeout, retry with the alternate address family.

  2. Medium-term: The createPinnedLookup function in ssrf-B5bGsnx-.js should properly support the {all: true} callback format that autoSelectFamily expects, returning an array of {address, family} records. The current implementation handles opts.all but the interaction with undici's Happy Eyeballs still breaks.

  3. Consider: Whether dedupeAndPreferIpv4 is the right default ordering for all environments. In IPv6-capable environments, keeping the system's natural DNS ordering (IPv6 first) may be preferable, especially for services known to work better over IPv6.

Related

  • Issue #23702 (closed) — addressed a different cross-target dedupe filtering bug in buildReplyPayloads, not this SSRF dispatcher issue

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