codex CLI hangs at `_dyld_start` on macOS 26 (Tahoe), never reaches main()

Open 💬 5 comments Opened May 21, 2026 by howie

Summary

codex CLI (any subcommand, including --version and --help) hangs indefinitely on macOS 26.4.1 (Tahoe). The process spawns but never enters the Rust runtime — sample(1) shows the main thread spending 100% of its time inside _dyld_start for the full 3-second sampling window. Zero bytes are written to stdout/stderr before the process is killed by timeout.

Other Rust binaries (ripgrep, etc.) and node start instantly on the same machine, so this is specific to the codex binary.

Environment

| | |
|---|---|
| codex version | 0.132.0 (Homebrew cask, also reproduces on 0.130.0) |
| macOS | 26.4.1 (Tahoe, build 25E253) |
| Kernel | Darwin 25.4.0 arm64 (xnu-12377.101.15~1) |
| Hardware | Apple Silicon (M-series, arm64) |
| Install method | brew install --cask codex |
| Binary path | /opt/homebrew/Caskroom/codex/0.132.0/codex-aarch64-apple-darwin |
| Binary size | 192 MB |
| codesign | Valid -- Developer ID Application: OpenAI OpCo, LLC (2DC432GLL2), Runtime Version 15.5.0, hardened runtime enabled |

Reproduction

$ time codex --version
# hangs forever, no output, must be killed

$ timeout 8 codex --version 2>&1
# exit code 124, zero bytes of output

Same behavior for every subcommand tested: --version, --help, review, etc.

Diagnostic evidence

1. Thread stack sample (decisive evidence)

$ codex --version &
$ sample $! 3
Analysis of sampling codex (pid 84221) every 1 millisecond
Process:         codex-aarch64-apple-darwin [84221]
OS Version:      macOS 26.4.1 (25E253)
Report Version:  7

Physical footprint:         112K
Physical footprint (peak):  112K
----

Call graph:
    2395 Thread_40008380: Main Thread   DispatchQueue_<multiple>
      2395 _dyld_start  (in dyld) + 0  [0x10dd389c0]

Sort by top of stack, same collapsed (when >= 5):
        _dyld_start  (in dyld)        2395

100% of 2395 samples (1 ms each) caught in _dyld_start. The process never advances past the dynamic linker entry point -- so this is not a Rust-runtime, OAuth, network, or auth.json issue. It is a dyld load-time deadlock.

2. lsof confirms no application-level activity

After ~1.5 s the hung process has only these file descriptors open:

codex-aar 61677 doxa  cwd    DIR   1,17   864       /Users/doxa/...
codex-aar 61677 doxa  txt    REG   1,17   192631440 .../codex-aarch64-apple-darwin
codex-aar 61677 doxa  txt    REG   1,17   2357376   /usr/lib/dyld
codex-aar 61677 doxa    0r   CHR    3,2   0t0       /dev/null
codex-aar 61677 doxa    1w   REG   1,17   0         /private/tmp/codex_out.txt
codex-aar 61677 doxa    2w   REG   1,17   0         /private/tmp/codex_out.txt

No sockets, no ~/.codex/auth.json read, no SQLite open, no keychain handles. Pure load-time hang.

3. DYLD_PRINT_LIBRARIES=1 reveals Apple ID / login framework chain

Visible portion of the dyld trace before the timeout:

dyld: move loaded to delayed: PushKit
dyld: move loaded to delayed: CoreTransferable
dyld: move loaded to delayed: NetAuth
dyld: move loaded to delayed: loginsupport
dyld: move loaded to delayed: CloudTelemetryTools
dyld: move loaded to delayed: CloudTelemetryShared.dylib
dyld: move loaded to delayed: AppleIDSSOAuthentication
dyld: move loaded to delayed: CryptoKitPrivate
dyld: move loaded to delayed: FindMyDevice
dyld: move loaded to delayed: ServiceManagement
dyld: move loaded to delayed: libCheckFix.dylib
dyld: move loaded to delayed: CoreServicesStore
dyld: move loaded to delayed: BackgroundTaskManagement
dyld: move loaded to delayed: libcurl.4.dylib
dyld: move loaded to delayed: libcrypto.46.dylib
dyld: move loaded to delayed: libssl.48.dylib
... (truncated)

That extensive private-framework chain (PushKit, AppleIDSSOAuthentication, FindMyDevice, CryptoKitPrivate, loginsupport) is unusual for a CLI and may interact poorly with Tahoe's stricter hardened-runtime / dyld closure checks.

4. Failed workarounds

| Workaround | Result |
|---|---|
| pkill -9 codex (kill stale processes) then retry | Still hangs |
| xattr -d com.apple.quarantine on binary | Still hangs |
| brew upgrade --cask codex (0.130.0 -> 0.132.0) | Still hangs |
| DYLD_USE_CLOSURES=0 codex --version | Still hangs (env var removed in macOS 26) |
| DYLD_SHARED_REGION=avoid codex --version | Still hangs |

5. Control: other binaries are fine

$ time rg --version
ripgrep 15.1.0
rg --version  0.00s user 0.00s system 14% cpu 0.022 total

$ time node --version
v25.8.2
node --version  0.01s user 0.01s system 58% cpu 0.027 total

Same machine, same shell, same dyld. Only codex hangs.

Hypothesis

The binary is signed with Runtime Version 15.5.0 (Sequoia SDK) and links a large surface of Apple ID / login frameworks. macOS 26 (Tahoe) appears to deadlock or otherwise refuse to complete dyld initialization for this specific binary before any code in main runs. A Tahoe-targeted rebuild (or trimming the Apple-private framework chain) would likely resolve this.

Asks

  1. Is a Tahoe-tested build planned, or is there a recommended Tahoe workaround?
  2. Is there a codex distribution channel (npm? direct release?) using a different binary build that we can try as a stopgap?
  3. Happy to share the full sample output, codesign -dvvvv, and any other diagnostics on request.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗