macOS background jobs detached from Aqua login-session bootstrap → DNS/TLS break after VPN reconnect

Status Fixed / completed
Maintainer reply None cached
Activity 0 comments · opened Jul 31, 2026 · closed Jul 31, 2026

Environment: Claude Code on macOS (Darwin 25.6), running as a background/headless job (not a foreground Terminal session).

Summary

A Claude Code background job's shell is not attached to the user's Aqua GUI-login Mach bootstrap namespace, so it cannot reach per-session mach services. Any restart of one of those daemons mid-session — most commonly a VPN reconnect restarting mDNSResponder — permanently breaks name resolution and TLS trust for the running job. Only direct-socket tools survive.

Impact

  • getaddrinfo fails → gh, git-over-HTTPS, node, python, curl <hostname> all get "could not resolve host"
  • TLS trust evaluation fails → Go / Security.framework clients (e.g. gh) fail with x509: OSStatus -26276
  • id -un returns the numeric uid; sudo → "you do not exist in the passwd database" (opendirectory)
  • scutil --dns / dscacheutil return empty (configd)

A long-running background job silently loses almost all network capability the moment the VPN reconnects, and never recovers.

Root cause (background job vs. real Terminal — same user, uid 501, same machine, same VPN)

| Probe | Background job | Real Terminal |
|---|---|---|
| launchctl managername | Could not get manager name | Aqua |
| id -un | 501 | arthur |
| getaddrinfo('github.com') | gaierror | resolves |
| dscacheutil -q host | empty | resolves |
| dig @8.8.8.8 github.com | works | works |
| curl --resolve host:443:IP | works (TLS ok) | works |

Direct-socket paths work; every mach-service-brokered path fails ⇒ the process is outside the Aqua bootstrap namespace. dangerouslyDisableSandbox does not help — it's the bootstrap namespace, not Seatbelt.

Reproduction

  1. Start a Claude Code background job on macOS; confirm gh/curl https://… work.
  2. Reconnect the VPN (or sudo killall -HUP mDNSResponder).
  3. From the job: gh pr view <n> or python3 -c "import socket; socket.getaddrinfo('github.com',443)" → fails.
  4. Same commands in Terminal.app (same user/VPN) → succeed.

Suggested fix

Launch macOS background jobs within the user login session so they inherit the Aqua mach bootstrap — spawn via launchctl asuser $(id -u) <cmd> / launchctl bsexec, or run as a per-user LaunchAgent (Aqua) rather than a detached/daemon (System) context. That restores mDNSResponder/trustd/opendirectory/configd access and lets the job survive daemon restarts (VPN reconnects).

Workaround

Run the task in a foreground/interactive Claude Code launched from Terminal. (GODEBUG=netdns=go restores DNS for Go tools but not TLS trust, so it's only partial.)

View original on GitHub ↗