Sandbox network egress broken on Linux: internal socat relay uses TCP-LISTEN (tries IPv6) and dies in --unshare-net namespace

Resolved 💬 1 comment Opened Jun 3, 2026 by AloNogram Closed Jul 7, 2026

Summary

On Linux, the Bash tool sandbox cannot reach the network. All proxied tools fail
with Failed to connect to localhost port 3128: Couldn't connect to server.

Root cause: Claude Code's internal egress relay is launched as

socat TCP-LISTEN:3128,fork,reuseaddr UNIX-CONNECT:/tmp/claude-http-<hex>.sock
socat TCP-LISTEN:1080,fork,reuseaddr UNIX-CONNECT:/tmp/claude-socks-<hex>.sock

inside the bwrap --unshare-net network namespace. socat's TCP-LISTEN
attempts to create an IPv6 listening socket first. The unshared network namespace
has no IPv6 support, so the syscall fails:

socat[NN] E socket(10, 1, 6): Address family not supported by protocol

(socket(10,1,6) = AF_INET6 / SOCK_STREAM / IPPROTO_TCP.) socat exits with
status 1, so nothing ever listens on localhost:3128 / localhost:1080, and every
proxied tool gets connection-refused.

Loopback is up inside the namespace (127.0.0.1/8 on lo), so this is not a
loopback issue — it is specifically IPv4-vs-IPv6 in the socat invocation.

Environment

  • Claude Code: 2.1.161
  • OS: Ubuntu 24.04.4 LTS, kernel 6.17.0-35-generic
  • bubblewrap: 0.9.0
  • socat: present at /usr/bin/socat
  • Sandbox filesystem/process isolation works fine (AppArmor profile in place for

Ubuntu 24.04 apparmor_restrict_unprivileged_userns=1).

Reproduction

  1. Linux host with the Bash sandbox enabled (--unshare-net).
  2. Run any networked command via the Bash tool, e.g. curl https://github.com.
  3. Observe Failed to connect to localhost port 3128.
  4. Inspect background jobs: the two socat TCP-LISTEN:... relays have exited 1.
  5. Run the relay manually to see the error:

``
socat TCP-LISTEN:3128,reuseaddr UNIX-CONNECT:/tmp/claude-http-<hex>.sock
# -> E socket(10, 1, 6): Address family not supported by protocol
``

Confirmed fix / workaround

Forcing IPv4 makes the entire egress chain work. Starting the relay with
TCP4-LISTEN instead of TCP-LISTEN:

socat TCP4-LISTEN:3128,fork,reuseaddr UNIX-CONNECT:/tmp/claude-http-<hex>.sock &
curl https://github.com    # -> HTTP 200

So the unix-socket → host relay → upstream proxy chain is fully functional; only
the address family in the in-namespace socat command is wrong.

Proposed change

Use TCP4-LISTEN (or pf=ip4) for the in-sandbox relay listeners, or ensure IPv6
is available in the unshared network namespace. TCP4-LISTEN is the minimal,
targeted fix.

Note: setting sandbox.network.allowAllUnixSockets: true is required for the unix
sockets to be reachable inside the namespace, but does not by itself fix this —
the relay still dies on the IPv6 socket creation.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗