openclaw - 💡(How to fix) Fix Gateway crashes ~39ms after 'ready' on os.networkInterfaces() in restricted sandboxes (mDNS sidecar @homebridge/ciao) [1 comments, 1 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#72939Fetched 2026-04-28 06:29:57
View on GitHub
Comments
1
Participants
1
Timeline
6
Reactions
0
Participants
Timeline (top)
cross-referenced ×4closed ×1commented ×1

Error Message

[openclaw] Unhandled promise rejection: SystemError: A system error occurred: uv_interface_addresses returned Unknown system error 1 at Object.networkInterfaces (node:os:218:16) at Function.assumeNetworkInterfaceNames (/usr/local/lib/node_modules/openclaw/node_modules/@homebridge/ciao/src/NetworkManager.ts:527:23) at NetworkManager.getCurrentNetworkInterfaces (...)

Root Cause

In plain English: when the gateway boots inside a sandbox that restricts os.networkInterfaces() (such as a NemoClaw / OpenShell pod), it crashes ~39ms after announcing "ready" because its mDNS sidecar (the @homebridge/ciao channel-discovery component) calls that syscall and gets a SystemError. The unhandled promise rejection kills the gateway. There's no recovery path baked in. The workaround is to set discovery.mdns.mode=off in openclaw.json — but most users won't know that setting exists or that mDNS is the cause until they read source.

Fix Action

Fix / Workaround

In plain English: when the gateway boots inside a sandbox that restricts os.networkInterfaces() (such as a NemoClaw / OpenShell pod), it crashes ~39ms after announcing "ready" because its mDNS sidecar (the @homebridge/ciao channel-discovery component) calls that syscall and gets a SystemError. The unhandled promise rejection kills the gateway. There's no recovery path baked in. The workaround is to set discovery.mdns.mode=off in openclaw.json — but most users won't know that setting exists or that mDNS is the cause until they read source.

Workarounds

Runtime workaround (used in our test):

"discovery": { "mdns": { "mode": "off" } }

in openclaw.json. Default is "minimal", options are off|minimal|full. Found via grep cfg.discovery?.mdns?.mode in dist/audit-D8YFKksP.js — the option is real and works, but it's not documented anywhere visible.

Code Example

[openclaw] Unhandled promise rejection: SystemError: A system error occurred:
  uv_interface_addresses returned Unknown system error 1
    at Object.networkInterfaces (node:os:218:16)
    at Function.assumeNetworkInterfaceNames (/usr/local/lib/node_modules/openclaw/node_modules/@homebridge/ciao/src/NetworkManager.ts:527:23)
    at NetworkManager.getCurrentNetworkInterfaces (...)

---

openshell sandbox exec -n <sandbox> -- /usr/local/bin/openclaw gateway
# Gateway starts, logs "ready", then dies ~39ms later with the trace above.

---

"discovery": { "mdns": { "mode": "off" } }

---

// In gateway startup, where ciao is initialized:
try {
  await initChannelDiscovery();
} catch (err) {
  log.warn(`[gateway] mDNS / channel discovery unavailable in this environment, continuing without: ${err}`);
}
RAW_BUFFERClick to expand / collapse

In plain English: when the gateway boots inside a sandbox that restricts os.networkInterfaces() (such as a NemoClaw / OpenShell pod), it crashes ~39ms after announcing "ready" because its mDNS sidecar (the @homebridge/ciao channel-discovery component) calls that syscall and gets a SystemError. The unhandled promise rejection kills the gateway. There's no recovery path baked in. The workaround is to set discovery.mdns.mode=off in openclaw.json — but most users won't know that setting exists or that mDNS is the cause until they read source.

Problem

The gateway starts cleanly inside a restricted sandbox, logs ready (6 plugins, 2.0s) with HTTP server listening on :18789, then ~39ms later crashes with:

[openclaw] Unhandled promise rejection: SystemError: A system error occurred:
  uv_interface_addresses returned Unknown system error 1
    at Object.networkInterfaces (node:os:218:16)
    at Function.assumeNetworkInterfaceNames (/usr/local/lib/node_modules/openclaw/node_modules/@homebridge/ciao/src/NetworkManager.ts:527:23)
    at NetworkManager.getCurrentNetworkInterfaces (...)

Source: @homebridge/ciao (mDNS sidecar used for channel discovery via Bonjour) calls Node's os.networkInterfaces(). The sandbox restricts that syscall — uv_interface_addresses returns Unknown system error 1. Promise rejection bubbles up; gateway exits.

Reproducer

Tested-against: OpenClaw v2026.4.9 inside a NemoClaw v0.0.26 sandbox (k3s pod with restricted syscalls).

openshell sandbox exec -n <sandbox> -- /usr/local/bin/openclaw gateway
# Gateway starts, logs "ready", then dies ~39ms later with the trace above.

Repro outside NemoClaw: any container that filters getrandom()/uv_interface_addresses syscalls (some hardened seccomp profiles, restricted Kubernetes pod security contexts) hits the same crash.

Workarounds

Runtime workaround (used in our test):

"discovery": { "mdns": { "mode": "off" } }

in openclaw.json. Default is "minimal", options are off|minimal|full. Found via grep cfg.discovery?.mdns?.mode in dist/audit-D8YFKksP.js — the option is real and works, but it's not documented anywhere visible.

Failed workaround: NODE_OPTIONS="--unhandled-rejections=warn" does NOT prevent the crash. The SystemError-class rejection mode flag may not catch this specific rejection type, or the gateway's signal handlers run before the --unhandled-rejections policy applies.

Proposed fix

Two complementary improvements:

1. Defensive try/catch around the ciao initialization.

networkInterfaces() can legitimately fail on restricted hosts (Landlock, seccomp, gVisor, Kata, Firecracker, etc.). The current code treats the failure as fatal; it should treat it as "no mDNS available, run without channel discovery."

// In gateway startup, where ciao is initialized:
try {
  await initChannelDiscovery();
} catch (err) {
  log.warn(`[gateway] mDNS / channel discovery unavailable in this environment, continuing without: ${err}`);
}

2. Detect "we're in a restricted sandbox" at startup and skip ciao entirely.

Heuristics that work:

  • Presence of /sandbox/.openclaw-data (NemoClaw signal).
  • os.networkInterfaces() returns empty / throws on probe.
  • An explicit OPENCLAW_DISABLE_MDNS=1 env var or discovery.mdns.mode=off config.

Pick one (config-based is most explicit) or all three (defense in depth).

3. Document discovery.mdns.mode in the user-facing config schema.

It's a real, working option — just not visible.

Alternatives considered

  • Patch upstream @homebridge/ciao to handle EAI errors gracefully. Out of scope for this repo and may take time to land. The defensive try/catch is the right shape regardless.
  • Replace ciao with a different mDNS library that handles restricted hosts. Too invasive for a scenario where mDNS isn't critical (channel discovery has fallbacks via explicit config).

Test plan

  • Unit: assert initChannelDiscovery() failure is caught and logged as WARN, gateway continues startup.
  • Integration: start gateway in a Linux container with seccomp filter blocking socket() for AF_NETLINK (effectively breaks networkInterfaces()); confirm gateway stays up.
  • Regression: gateway with mDNS available continues to work as before.

Risk / blast radius

  • Loses mDNS-based channel discovery in restricted environments. Acceptable because (a) mDNS doesn't work in those environments anyway, (b) explicit channel config via openclaw.json already works there.
  • No code-path change in non-restricted environments. Try/catch is around the init; if init succeeds (the common case), nothing changes.

Open questions

  1. Is discovery.mdns.mode=off the canonical way to disable mDNS, or is there a different / preferred mechanism the maintainers would prefer to expose?
  2. Should the gateway also skip mDNS automatically when running under known sandbox runtimes (NemoClaw/OpenShell, gVisor, Firecracker, etc.), or stick with explicit config?
  3. Is there appetite for a --no-mdns CLI flag mirroring the config option?

This is one of a small batch of gateway-lifecycle / plugin-install findings from a recent end-to-end test of the deep-observability plugin under NemoClaw. Sibling issues being filed for openclaw plugins install <path> rejecting valid paths, plugin async register() silently truncated, openclaw gateway stop no-op, and double plugin-load timing.

extent analysis

TL;DR

The most likely fix is to add a defensive try/catch around the ciao initialization to handle the SystemError rejection when os.networkInterfaces() fails in restricted sandboxes.

Guidance

  • Implement a try/catch block around the initChannelDiscovery() call to catch and log the SystemError rejection, allowing the gateway to continue startup.
  • Consider detecting restricted sandboxes at startup and skipping ciao initialization altogether using heuristics such as the presence of /sandbox/.openclaw-data or an explicit OPENCLAW_DISABLE_MDNS=1 env var.
  • Document the discovery.mdns.mode config option in the user-facing config schema to allow users to explicitly disable mDNS.

Example

try {
  await initChannelDiscovery();
} catch (err) {
  log.warn(`[gateway] mDNS / channel discovery unavailable in this environment, continuing without: ${err}`);
}

Notes

The proposed fix assumes that the SystemError rejection is the primary cause of the crash, and that catching and logging the error will allow the gateway to continue running. However, further testing and verification are necessary to ensure that this fix resolves the issue.

Recommendation

Apply the workaround by adding a defensive try/catch around the ciao initialization, as this is a relatively simple and non-invasive change that can help mitigate the issue. Additionally, consider documenting the discovery.mdns.mode config option to provide users with a clear way to disable mDNS if needed.

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 - 💡(How to fix) Fix Gateway crashes ~39ms after 'ready' on os.networkInterfaces() in restricted sandboxes (mDNS sidecar @homebridge/ciao) [1 comments, 1 participants]