Codex macOS build missing NSLocalNetworkUsageDescription causing remote control enrollment failure

Open 💬 7 comments Opened Jun 13, 2026 by Alilioooo

Environment

  • macOS: [26.5.1]
  • Codex Desktop: latest (upgraded recently)
  • iPhone ChatGPT app: latest
  • Account: MFA enabled
  • Passkey enabled

Problem

Trying to connect iPhone ChatGPT to Mac Codex for remote control.

iPhone shows:

"Couldn't enable remote control. Try again"

What I observed

  1. Authentication works normally
  2. MFA is enabled
  3. Re-login does not fix it
  4. Removing Codex cache does not fix it
  5. Removing Keychain entries does not fix it
  6. Reinstalling/restarting does not fix it

Important:

Codex does NOT appear under:

System Settings -> Privacy & Security -> Local Network

Only ChatGPTHelper appears.

Bundle ID:

com.openai.codex

Config

~/.codex/config.toml:

[features]
js_repl = false
remote_connections = true

This key persists after restart.

Expected

Codex should request Local Network permission and complete remote enrollment.

Actual

Remote control enable fails immediately.
No Local Network permission prompt.
No remote enrollment token created in Keychain.

Additional notes

Looks like embedded remote host/app-server never initializes or never reaches local network entitlement trigger.

Critical finding:

Running:

plutil -p /Applications/Codex.app/Contents/Info.plist | grep NSLocalNetworkUsageDescription

returns nothing.

This suggests the app bundle does not declare Local Network usage.

As a result:

  • Codex never appears in macOS Local Network permissions
  • no permission prompt is shown
  • iPhone remote control fails with "Couldn't enable remote control"

➜ ~ sw_vers
ProductName: macOS
ProductVersion: 26.5.1
BuildVersion: 25F80
➜ ~ defaults read /Applications/Codex.app/Contents/Info CFBundleShortVersionString
26.609.30741
➜ ~ plutil -p /Applications/Codex.app/Contents/Info.plist | grep -i network
➜ ~

View original on GitHub ↗

7 Comments

Alilioooo · 2 months ago

error is shown on Mac Codex Desktop, not on iPhone

xianrenzhou · 2 months ago

also have same problem

tyouengun · 2 months ago

Additional reproduction — Mac-to-Mac, version 26.609.71450, macOS 26.6 beta2
Environment

Host: Mac Studio (Apple Silicon), macOS 26.6 beta2
Controller: MacBook Air (Apple Silicon), macOS 26.6 beta2
Both machines: Codex Desktop 26.609.71450 (updated Jun 16, then again Jun 17, 2026)
ChatGPT subscription: Pro
Account: MFA enabled

Symptom

Mac-to-Mac remote control is permanently stuck at "Connecting". The handshake never completes. Re-pairing multiple times does not help — the connection attempt fails before the handshake on most attempts. iPhone (iOS 26.6 beta2, latest ChatGPT app, same account) connects to the Mac Studio host normally via cloud relay, confirming the host enrollment itself is not the issue.
Confirmed reproduction of the missing key — on both machines
plutil -p /Applications/Codex.app/Contents/Info.plist | grep -i NSLocalNetworkUsageDescription
Returns empty on both Mac Studio (host) and MacBook Air (controller). Neither machine shows Codex under System Settings → Privacy & Security → Local Network. No Local Network permission prompt has ever appeared.
Update history

Jun 16 update (26.609.71450): key absent
Jun 17 update (same version string pushed again): key still absent

The Jun 17 update did not fix this. The missing NSLocalNetworkUsageDescription entry persists across both updates. Mac-to-Mac remote control remains completely non-functional.

Alilioooo · 2 months ago

I found the root cause.

This is not a Codex account or iPhone issue.

In my case, Codex Remote Control does not properly inherit the system proxy settings. It tries to connect directly to OpenAI relay (likely via HTTP2/WebSocket), which fails on my network unless traffic is transparently proxied (TUN mode).

That explains why:

  • TUN mode ON → works
  • System proxy / normal Clash rules → does NOT work

The fix is to explicitly set proxy environment variables for Codex.

Create this file:

macOS:
~/.codex/.env

Windows:
C:\Users<username>.codex.env

Add:

HTTP_PROXY=http://127.0.0.1/:<your_http_proxy_port>
HTTPS_PROXY=http://127.0.0.1/:<your_http_proxy_port>
ALL_PROXY=http://127.0.0.1/:<your_http_proxy_port>
WS_PROXY=http://127.0.0.1/:<your_http_proxy_port>
WSS_PROXY=http://127.0.0.1/:<your_http_proxy_port>

NO_PROXY=localhost,127.0.0.1,::1

Then fully restart Codex.

After that, Remote Control works without enabling TUN.

This confirms Codex supports proxy env vars, but may not correctly use system proxy settings by default.

tyouengun · 2 months ago

Still stuck on 'Connecting' after testing your env config (no errors thrown). For Mac-to-Mac remote control: proxy is ruled out as the root cause. The issue appears to be a missing NSLocalNetworkUsageDescriptionin Info.plist.

HAOoool · 11 days ago
AI authorship disclosure: This comment was authored by an AI agent running on the reporter's machine, based on a live debugging session with the human operator. All findings below were verified with real tool output (direct reads of the authorization store, unified system logs, controlled experiments). Full details: https://github.com/NousResearch/hermes-agent/issues/81563#issuecomment-5309147670

Same class of bug — we investigated this in our project (Hermes desktop) and found the mechanism; please verify in your environment

We hit the identical symptom (Electron app, macOS 27, LAN access silently denied, no Local Network permission prompt ever) and spent two nights isolating it. Everything below was verified on our setup (macOS 27.0 26A5406e, Hermes desktop, standard electron-builder packaging). Your case may differ — but the check methods are included so you can verify quickly.

1. The prompt can be suppressed for locally-built Electron apps, so the grant never gets created.
macOS only shows the Local Network alert for programs in the undetermined state (TN3179 / WWDC20-10110 / WWDC24-10123). For our locally-built Electron shell, the responsible-process bundle ID resolved to (null) at judgment time, so the system fell back to the Electron framework UUID — and that fallback was gated by Electron's own grant state. Once any Electron app on the machine had been granted or denied Local Network, fresh bundle IDs never saw a prompt again. No prompt → no grant → permanent No route to host / EHOSTUNREACH.

2. The grant store is per bundle ID (and per interpreter path).
Grants live in /Library/Preferences/com.apple.networkextension.plist → PathController.Rules (NSKeyedArchiver), keyed by SigningIdentifier (bundle ID) or Path. System Settings → Privacy & Security → Local Network toggles write exactly this file (verified bidirectionally in our session). Undetermined rules carry DenyMulticast=True; granted ones DenyMulticast=False. You can read this file directly to see whether your app has a rule at all.

3. The usage-description key was not the fix in our case.
We packed NSLocalNetworkUsageDescription into the app (verified present in the built Info.plist) — a fresh bundle ID still never prompted and never connected. It is still worth adding as intent declaration, but it did not trigger the prompt for our class of app.

4. A workaround that worked for us (single-variable experiment).
Build/run with the same bundle ID as a signed release that has been granted once (or run the signed release once and accept the prompt). We took an Apple-Development-signed local build that was permanently denied under a fresh bundle ID, changed only appId in package.json to the granted ID, rebuilt — and it connected immediately. The grant survived arbitrary rebuilds (adhoc re-signing, repacks).

5. Quick check on an affected machine.
Settings → Privacy & Security → Local Network: if there is an existing "Electron" / "python3.11" / other entry, the fresh app's prompt may be suppressed by that entry's decision. Granting/toggling that entry changes nothing for the fresh bundle ID; the fresh ID needs its own rule, which only a prompt can create.

Our interpretation: an Electron responsible-process identity issue (bundle ID → null) interacting with macOS's per-bundle grant model. This may affect every Electron app on macOS — possibly worth an upstream (Electron) report eventually.

Full write-up with the complete test matrix, logs, grant-store dumps, and methodology: https://github.com/NousResearch/hermes-agent/issues/81563#issuecomment-5309147670

JeffreyEarly · 9 days ago

I can provide a reproducible case showing that the ChatGPT desktop Remote Control WebSocket ignores proxy environment variables, even when those variables are present in the desktop process.

Environment

  • macOS 26.6.1 (25G76), arm64
  • ChatGPT desktop 26.814.41407, build 6720
  • Bundled Codex CLI: 0.148.0-alpha.15
  • Corporate network requires an HTTP CONNECT proxy for external traffic
  • Direct outbound TCP 443 is blocked by policy

Proxy configuration tested

The following variables were configured in ~/.codex/.env:

HTTP_PROXY
HTTPS_PROXY
ALL_PROXY
WS_PROXY
NO_PROXY

I also launched the desktop executable directly after exporting the file:

set -a
source ~/.codex/.env
set +a
/Applications/ChatGPT.app/Contents/MacOS/ChatGPT

Inspection of the running ChatGPT process confirmed that these variables were actually present:

HTTP_PROXY
HTTPS_PROXY
ALL_PROXY
WS_PROXY
NO_PROXY
http_proxy
https_proxy
no_proxy

Therefore, this does not appear to be a .env loading or GUI-process inheritance problem.

Reproduction

  1. Run ChatGPT desktop on a network where external traffic must use an HTTP CONNECT proxy.
  2. Configure the proxy variables above.
  3. Fully restart ChatGPT, or launch its executable from a shell containing the variables.
  4. Attempt to use Remote Control / “Control other devices.”

Actual behavior

The normal HTTPS enrollment requests succeed, including token refresh:

[remote-control-websocket] remote_control_client_refresh_finish_response
scopes=["remote_control_controller_websocket"]

The subsequent Remote Control WebSocket fails before opening:

[remote-control-transport]
remote_control_websocket.connect_failed_before_open
errorCode=ECONNREFUSED
errorName=AggregateError
errorStack="AggregateError [ECONNREFUSED]:
    at internalConnectMultiple (node:net:1142:49)
    at afterConnectMultiple (node:net:1723:7)"

This repeats on every reconnect attempt.

Independent tests from the same machine show:

curl --proxy http://<proxy-host>:<port> https://ws.chatgpt.com/

successfully establishes the proxy CONNECT/TLS connection and receives an HTTP response (404, as expected for /).

In contrast:

curl --noproxy '*' https://ws.chatgpt.com/

fails immediately with connection refused, matching the desktop application’s error.

This strongly indicates that the Remote Control WebSocket is attempting a direct node:net connection instead of tunneling through the configured proxy.

Expected behavior

The wss://ws.chatgpt.com connection should honor HTTPS_PROXY/https_proxy and NO_PROXY/no_proxy, using HTTP CONNECT for the TLS WebSocket connection. Authenticated HTTP proxies should ideally be supported as well.

Possible implementation boundary

The failing stack originates in the ChatGPT desktop Electron process (app.asar), rather than the spawned Codex app-server. This suggests that applying proxy configuration only to app-server would not fix controller-side Remote Control connections; the proxy agent likely needs to be applied where the desktop process constructs the Remote Control WebSocket.

I am separately working with IT on allowing a direct connection as a temporary workaround, but that does not resolve the underlying proxy-support issue.

I can provide a sanitized desktop log or feedback session ID if useful.