Skip to content

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

@howie

Description

@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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingperformance

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions