macOS: session processes are denied Local Network access despite the grant (bundle_id: (null) at evaluation)

Status Open
Reported on v2.1.275
Maintainer reply None cached
Activity 1 comment · opened Sep 20, 2026

Summary

On macOS, every process spawned by a Claude Code session inside the Claude desktop app is denied
Local Network access, even though /Applications/Claude.app has been granted it in System
Settings. connect() to any address on a directly-attached subnet returns EHOSTUNREACH
immediately; the tailnet and the public internet are unaffected, so it presents as a routing fault
rather than a permissions one.

The cause appears to be attribution: the responsible process is the versioned helper bundle
~/Library/Application Support/Claude/claude-code/<version>/claude.app/Contents/MacOS/claude,
which is correctly signed as com.anthropic.claude-code, but macOS evaluates the connection with
bundle_id: (null) — so the grant recorded against com.anthropic.claudefordesktop cannot
apply, and the default is deny.

Environment

  • macOS 27.0 (26A428), Apple silicon
  • Claude desktop 2.2553.1
  • Claude Code helper 2.1.275 (2.1.271 also present on disk)

Evidence

At the moment of each blocked connect, with an ordinary Python socket to a host on the local
subnet:

UserEventAgent[357] [com.apple.networkextension:] Got local network blocked notification:
    pid: 2194, uuid: 4C4C4493-…, bundle_id: (null)
kernel: tcp drop outgoing [<IPv4-redacted>:51822<-><IPv4-redacted>:2222] interface: en0
    process: Python:2999 t_state: SYN_SENT so_error: 0 reason: NECP

pid 2194 is the session's parent:

2194  2190  …/Claude/claude-code/2.1.275/claude.app/Contents/MacOS/claude …
2190  2022  /Applications/Claude.app/Contents/Helpers/disclaimer
2022     1  /Applications/Claude.app/Contents/MacOS/Claude

and that bundle is properly identified and signed:

$ codesign -dv …/claude-code/2.1.275/claude.app
Identifier=com.anthropic.claude-code
TeamIdentifier=Q6L2SF6YDW
$ plutil -p …/Contents/Info.plist | grep CFBundleIdentifier
  "CFBundleIdentifier" => "com.anthropic.claude-code"

The only Local Network client recorded for Anthropic is the desktop app:

$ sudo plutil -convert xml1 -o - /var/db/locationd/clients.plist | …
com.anthropic.claudefordesktop | /Applications/Claude.app | registered: True

The control that isolates it

Same machine, same user, same binary, same second — once via launchctl submit, once from the
session's own shell:

| target | launchd-spawned | Claude Code session |
|---|---|---|
| gateway :443 | OPEN | EHOSTUNREACH |
| LAN host :2222 | OPEN | EHOSTUNREACH |
| LAN host :5000 | OPEN | EHOSTUNREACH |
| LAN host :22 | OPEN | EHOSTUNREACH |

The LAN is healthy throughout — other applications hold dozens of established TCP connections to
those same hosts while the session cannot open one.

Reproduction

  1. Run Claude Code inside the Claude desktop app on macOS 15+.
  2. Grant /Applications/Claude.app Local Network access in System Settings → Privacy & Security.
  3. From the session, connect to anything on your own subnet:

python3 -c "import socket;s=socket.socket();print(s.connect_ex(('192.168.x.y',443)))"

  1. Result: 65 (EHOSTUNREACH), instantly. The same command from a launchctl submit job on the

same machine returns 0.

What does not fix it

  • Granting /Applications/Claude.app Local Network access (already granted, registered: True).
  • Quitting and reopening the desktop app.
  • Toggling the generic claude.app entry in the Local Network list off and on.
  • dangerouslyDisableSandbox on the Bash tool, so it is not Claude Code's own sandbox.
  • Trying a different interpreter — Apple's /usr/bin/python3, Homebrew's python3.12, and

/usr/bin/curl all fail identically, so it is the process tree and not one binary's grant.

The single exception is a configured DNS resolver on the LAN, which connects because macOS exempts
those from the local-network rule.

Impact

Any workflow where Claude Code has to reach the machine's own network is silently impossible:
home-lab and on-prem hosts, printers, local databases and dev servers on another machine, private
registries, and DNS to a LAN resolver. Because lookups to LAN nameservers fail too, name resolution
breaks in ways that look unrelated — in this case a public resolver had to be added to the Mac's
DNS list before the session could resolve anything at all.

It is also very hard to recognise: the error is EHOSTUNREACH with a valid route and a populated
ARP entry, which is indistinguishable from a dead network unless you happen to compare against
another process on the same host.

Suggestion

Whatever establishes the responsible-process attribution for the session's children should resolve
to a bundle identifier, so that a grant made against the app actually covers them — either by
having the helper inherit com.anthropic.claudefordesktop, or by registering
com.anthropic.claude-code as its own Local Network client that the user can grant once and that
survives a version bump (the bundle path contains the version, so any per-path grant goes stale on
every update).

View original on GitHub ↗

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