Skip to content

WSL2: os.networkInterfaces() can throw uv_interface_addresses and crash gateway/status/tailnet paths #44180

@QuinnRuth

Description

@QuinnRuth

Summary

On WSL2, OpenClaw can crash or misbehave because os.networkInterfaces() throws ERR_SYSTEM_ERROR: uv_interface_addresses returned Unknown system error 1.

This impacts multiple CLI/runtime paths:

  • openclaw gateway
  • openclaw gateway status
  • openclaw status
  • tailnet/presence helpers used by status and gateway bootstrap

In our environment, this caused a very confusing failure mode:

  • gateway process existed and port 18789 was listening
  • local RPC probe initially timed out or failed
  • openclaw gateway status crashed instead of reporting health
  • openclaw status also crashed before showing useful diagnostics

This looks like a WSL-specific robustness bug in network-interface discovery code paths.

Environment

  • OpenClaw: 2026.3.2
  • Node: 24.11.0
  • OS: linux 6.6.87.2-microsoft-standard-WSL2
  • Runtime: WSL2 on Windows 11
  • Gateway mode: local loopback, token auth

Reproduction

On affected WSL2 environments, run:

openclaw gateway

or:

openclaw gateway status
openclaw status

Observed errors included:

SystemError [ERR_SYSTEM_ERROR]: A system error occurred: uv_interface_addresses returned Unknown system error 1

and later:

TypeError: Cannot read properties of undefined (reading 'ipv4')

from tailnet helpers when interface enumeration failed and returned no data.

What appears to be happening

There are multiple places in the built CLI/runtime that assume os.networkInterfaces() always succeeds and that helper results are always defined.

At least these paths were involved locally:

  • dist/net-*.js -> pickPrimaryLanIPv4()
  • dist/ws-*.js -> pickPrimaryLanIPv4() duplicate bundle copy
  • dist/daemon-cli.js -> another bundled copy
  • dist/tailnet-*.js -> pickPrimaryTailnetIPv4() / pickPrimaryTailnetIPv6() assume listTailnetAddresses() returns an object

When os.networkInterfaces() throws under WSL, OpenClaw should degrade gracefully to undefined / hostname fallback, not crash the CLI or gateway bootstrap/status paths.

Local workaround that fixed it

We patched the installed build locally to add defensive guards:

  1. Wrap os.networkInterfaces() in try/catch
  2. Return undefined instead of throwing from pickPrimaryLanIPv4()
  3. Use optional chaining for tailnet helpers:
return listTailnetAddresses()?.ipv4?.[0];
return listTailnetAddresses()?.ipv6?.[0];

After that:

  • openclaw status became usable again
  • openclaw gateway probe --timeout 10000 returned reachable + RPC ok
  • troubleshooting became possible without blind patching

Expected behavior

On WSL2 or any environment where interface enumeration fails:

  • gateway
  • gateway status
  • status
  • tailnet/presence reporting

should all degrade gracefully and continue with:

  • hostname fallback
  • missing-LAN-IP fallback
  • missing-tailnet-address fallback

rather than throwing fatal exceptions.

Why this matters

This is not just cosmetic.

When OpenClaw is already in a degraded networking state (proxy changes, WSL mirrored networking quirks, etc.), operators most need status/gateway status to work. Right now those commands can be the first thing that crashes, which makes the system much harder to recover.

Additional notes

We also saw transient gateway states where:

  • TCP connect to ws://127.0.0.1:18789 was ok
  • short probe budgets timed out
  • longer probe budgets succeeded

That part may be a separate startup-latency issue, but the networkInterfaces() crash was definitely a direct blocker and should be fixed independently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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