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

Status Closed — not planned
Reported on v2.1.161
Maintainer reply None cached
Activity 1 comment · opened Jun 3, 2026 · 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 ↗