You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Codex CLI v0.120.0 (Rust) hangs at _dyld_start on macOS 26.4.1 Tahoe — Gatekeeper/AppleSystemPolicy blocks Homebrew Cask binary #17447
Update (2026-04-12): Original diagnosis was incorrect — the issue is not about code signing format but about missing Apple notarization + macOS 26's persistent quarantine database. Not version-specific (both v0.119.0 and v0.120.0 work when downloaded directly). See my follow-up comment for revised root cause and fix.
What version of Codex is running?
codex-cli 0.120.0 (Rust rewrite, installed via Homebrew Cask)
What subscription do you have?
Plus
Which model were you using?
N/A — binary never launches
What platform is your computer?
macOS 26.4.1 Tahoe (Build 25E253), Mac mini, Apple Silicon
What issue are you seeing?
The Codex CLI binary installed via brew install --cask codex hangs indefinitely on launch. The process gets stuck at _dyld_start — the dynamic linker never loads a single library. No output, no error, no Gatekeeper dialog (accessed via SSH).
Diagnosis:
sample shows 100% of samples stuck at _dyld_start (in dyld) + 0
DYLD_PRINT_LIBRARIES=1 produces zero output — no libraries loaded
spctl --assess --type execute returns: rejected (the code is valid but does not seem to be an app)
com.apple.provenance xattr is present (SIP-protected, cannot be removed)
The binary is validly signed but macOS AppleSystemPolicy silently kills it before dyld completes
Workaround:
Copying the binary to a new location strips com.apple.provenance, then ad-hoc re-signing makes it work:
Thanks for the bug report. Has this worked for you in previous version? I'm trying to determine if this was a regression in 0.120.0 specifically. If you install 0.119.0, does that work for you?
I did further testing today and the results change the diagnosis significantly:
Version testing:
v0.119.0 downloaded directly from GitHub releases → works
v0.120.0 downloaded directly from GitHub releases → also works
v0.120.0 installed via brew install --cask codex → hangs
So this is not a regression between versions. Both work fine when downloaded directly.
Root cause (revised):
The issue is the interaction between Homebrew Cask and macOS 26's Gatekeeper:
Homebrew Cask downloads the tarball and macOS sets com.apple.quarantine on the extracted binary
spctl --assess --type execute returns rejected — the binary is properly signed (Developer ID) but not notarized
On macOS 26, the kernel blocks execution of quarantined + unnotarized binaries before dyld even starts
Crucially, xattr -d com.apple.quarantine does not fix it — macOS 26 persists the quarantine state in a system-level database (not just the xattr)
Copying the binary to a new path (new inode) bypasses the quarantine DB and works immediately — no re-signing needed
# This works without any re-signing:
cp /opt/homebrew/Caskroom/codex/0.120.0/codex-aarch64-apple-darwin /tmp/codex
/tmp/codex --version # codex-cli 0.120.0
Suggested fix:
Submit the release binaries to Apple's notary service (xcrun notarytool submit). Once notarized, Gatekeeper will allow execution even with quarantine. This would fix Homebrew Cask installs on macOS 26 permanently.
Workaround for users:
Use the official install script instead of Homebrew Cask — it downloads directly to ~/.local/bin/ without triggering Homebrew's quarantine:
curl -fsSL https://github.com/openai/codex/releases/download/rust-v0.120.0/install.sh | sh
I'll also correct my original issue description — the earlier hypothesis about "obsolete code signature format" was wrong. The signing is fine; the missing piece is notarization.
Interesting. I re-install it via Homebrew today (the same v0.120.0) and it runs without error. Assuming you haven't silently replaced the binary, it might be a glitch at the Apple side?
BTW: you should warn users NEVER run xattr -d com.apple.quarantine when such issue happens :)
Confirming this still reproduces on codex-cli 0.122.0 / macOS 26 Tahoe (Darwin 25.3) / Apple Silicon, installed via brew install --cask codex.
One correction to the workaround: cp does not strip com.apple.provenance on my system — the xattr is still present on the copied file at /tmp. What actually fixes the hang is the ad-hoc resign alone:
After this, codex --version works at the original Caskroom path even though com.apple.provenance is still on the inode. So the trigger seems to be the combination of the original signature + provenance, not the xattr's presence.
So in this case it was not a Codex runtime hang. The process was created but never resumed before dyld completed. Clearing visible com.apple.quarantine was insufficient; creating a new inode for the same signed bytes fixed it. This seems consistent with macOS 26.4.1 / AppleSystemPolicy retaining launch-blocking state for the original Homebrew Cask artifact outside the normal visible xattr path.
(Previous comment removed — posted prematurely before the full fix was identified. This is the corrected version.)
macOS 26.4.1 (25E253), Darwin 25.4.0, ARM64 — Codex v0.128.0 via Homebrew Cask — two separate issues, both triggered by the Cask install path
Following up on #17447 (comment) — the inode-replacement fix alone was not sufficient here. The full fix required both ad-hoc re-signingandmoving the binary out of the Caskroom directory tree.
Symptoms (identical to OP)
Any codex command hangs immediately, zero output, 0% CPU
sample <pid>: every sample at _dyld_start
vmmap -summary <pid>: "Process exists but has not started -- it is launched-suspended"
spctl --assess --type execute -vv: rejected (the code is valid but does not seem to be an app)
What was tried, in order
#
Attempt
Result
Why
1
xattr -d com.apple.quarantine on the binary
Still hung
Block is not stored in visible xattrs
2
xattr -rd com.apple.quarantine on the entire Caskroom tree
Still hung
Same
3
cp binary to /tmp (fresh inode, clean path)
Still hung
Block had escalated to CDHash level — all copies of those signed bytes blocked system-wide
4
cp + rm + mv to force new inode at original path
Still hung
Same CDHash = same cached block
5
brew reinstall --cask codex
Still hung
Re-downloads identical signed bytes
6
codesign --remove-signature
Killed with SIGKILL (exit 137) — no output at all, even --version
Ad-hoc signature avoids both the Developer ID heuristic AND the unsigned-binary kill
8
Copy the ad-hoc signed binary into the Caskroom path
Hangs again ❌
The Caskroom directory itself had com.apple.quarantine, and binaries placed inside it inherited the launch-suspended behavior
9
Place ad-hoc signed binary directly in /opt/homebrew/bin/ + symlink
Works ✅
Bypasses the quarantined directory entirely
What actually fixed it
# 1. Copy binary out of the quarantined Caskroom directory
cp /opt/homebrew/Caskroom/codex/0.128.0/codex-aarch64-apple-darwin \
/opt/homebrew/bin/codex-aarch64-apple-darwin
# 2. Ad-hoc sign (avoids Developer ID heuristic + avoids unsigned-binary kill)
codesign -s - /opt/homebrew/bin/codex-aarch64-apple-darwin
xattr -c /opt/homebrew/bin/codex-aarch64-apple-darwin
# 3. Point symlink to the clean location
rm -f /opt/homebrew/bin/codex
ln -sf /opt/homebrew/bin/codex-aarch64-apple-darwin /opt/homebrew/bin/codex
# 4. Clean the Caskroom dir quarantine so it doesn't poison future files
xattr -d com.apple.quarantine /opt/homebrew/Caskroom/codex/0.128.0
After this, codex --version prints codex-cli 0.128.0 and exits 0 normally.
Two distinct mechanisms at play
CDHash-level launch-suspension — AppleSystemPolicy caches a deny decision keyed on the binary's code directory hash. Once the Developer ID-signed binary has been blocked, all copies of those bytes are launch-suspended system-wide, regardless of path or inode. This is why brew reinstall (downloading the same signed bytes) doesn't help.
Quarantined directory poisoning — The com.apple.quarantine xattr on the Caskroom directory (/opt/homebrew/Caskroom/codex/0.128.0/) propagates to any executable placed inside it, re-triggering the launch-suspension even for binaries that work fine from /tmp or /opt/homebrew/bin/.
The earlier inode-replacement workaround likely worked because (a) the block hadn't yet escalated to CDHash-level on that machine and (b) the directory quarantine was cleared first. By the time a machine hits exit-137-on-unsigned behavior, both issues need to be addressed.
Reproduces on Codex 0.130.0 — and the SSH/remote case makes it much worse than a typical Gatekeeper prompt
Adding a data point that highlights why this is more severe than a one-time consent dialog:
macOS 26.4.1 (25E253) / Darwin 25.4.0 / Apple Silicon
codex-cli 0.130.0 via brew install --cask codex — same _dyld_start hang, Process exists but has not started -- it is launched-suspended, signed by OpenAI OpCo, LLC (2DC432GLL2) but not notarization-stapled (xcrun stapler validate → "does not have a ticket stapled to it").
Triggered by a routine brew upgrade, not a fresh install. Every Cask update re-applies com.apple.quarantine and re-arms the prompt, so this recurs on every release.
The host is headless / SSH-only. The Gatekeeper consent dialog ("codex-aarch64-apple-darwin" is an app downloaded from the Internet. Are you sure you want to open it?) is rendered on the local console, where there's no human to dismiss it. From the SSH side, codex simply hangs forever with no output, no error, and no indication that a UI prompt is the blocker. Diagnosing it requires sample <pid> (everything at _dyld_start) plus log show --predicate 'process == "syspolicyd"' to even realize Gatekeeper is involved.
In my case the only way to find out was connecting via Screen Sharing and seeing the dialog already open on the desktop.
This effectively bricks codex on every CI runner, build server, and remote-dev box on macOS 26 until someone physically (or via remote desktop) clicks "Open" — ssh alone cannot recover the machine.
The proposed fix earlier in this thread — notarizing release binaries with xcrun notarytool submit — would resolve this cleanly: notarized + stapled binaries don't trigger the first-launch consent dialog, so headless installs via Homebrew Cask would just work.
First, thanks to @g-taki for the meticulous original diagnosis and the revised root-cause writeup, to @cuber for the cleaner in-place resign variant, to @ashwch for the comprehensive workaround that actually unblocked me, to @cossio for the most recent confirmation on 0.130.0, and to @etraut-openai for engaging on triage. This thread is the single best resource on the bug.
Still reproducing on Codex CLI 0.130.0 / macOS 26.4.1 Tahoe (build 25E253) as of 2026-05-15 — and on this machine the simpler in-place resign workaround was not sufficient.
Posting an additional data point because the workaround selection seems to be machine-dependent, and the OS-level signature here is identical to what @g-taki and @ashwch already reported. Hopefully this helps anyone (or any AI coding assistant) landing on this issue while trying to figure out why codex hangs with no output on macOS Tahoe.
Environment
Mac mini, Apple Silicon (ARM64), macOS 26.4.1 Tahoe, build 25E253, Darwin 25.4.0
codex-cli 0.130.0 installed via brew install --cask codex
Signed by OpenAI OpCo, LLC (2DC432GLL2) (Developer ID), xcrun stapler validate reports no notarization ticket
Headless usage over SSH (driven by Claude Code), Gatekeeper consent dialog was not visible on the local console
Symptoms (matching the OP exactly)
Every codex invocation hung indefinitely. codex --version, codex --help, even codex completion zsh and codex completion fish (spawned automatically by shell startup) all hung. Six unkillable codex-aarch64-apple-darwin processes had silently accumulated through the day — every new terminal that loaded zsh/fish completions spawned another doomed instance.
sample <pid> 2 -mayDie: 100% of samples at _dyld_start (in dyld) + 0, physical footprint stuck at 112K, peak 112K (i.e. dyld never loaded a single library)
lsof -p <pid>: zero TCP sockets, only the codex binary mapped + dyld + redirected stdio. No network reached, no config loaded.
vmmap -summary <pid>: "Process exists but has not started -- it is launched-suspended" (matches @ashwch's report)
spctl --assess --type execute -vv on the binary: rejected (the code is valid but does not seem to be an app)
SIGTERM ignored. SIGKILL eventually landed but took several seconds — consistent with the process being suspended in a mach-port wait for an AppleSystemPolicy verdict that never came.
If you're an LLM-assisted developer searching for codex hangs, codex no output, codex --version hangs forever, codex stuck at dyld start macOS Tahoe, brew install cask codex broken, AppleSystemPolicy launched-suspended, OpenAI codex SIGKILL macOS 26, homebrew codex notarization, or codex completion zsh hangs — yes, this is the issue, and the comments below contain the fix.
Workaround comparison on this machine
Approach
Result
Notes
xattr -d com.apple.quarantine on the binary
Still hung
Quarantine state is persisted at the system policy DB level, not just the xattr (matches @g-taki's revised finding)
@cuber's in-place fix: cp → codesign --force -s - → mv back to Caskroom
Still hung
Adhoc signature was confirmed (Signature=adhoc, new Identifier codex-clean-<sha1>), xattr cleared, but codex --version still timed out at 15s.
@ashwch's full fix: move binary out of Caskroom to /opt/homebrew/bin/, adhoc-sign there, repoint the codex symlink, clear Caskroom dir quarantine
Works.codex --version returns codex-cli 0.130.0 in ~1.4s, exit 0.
This is consistent with @ashwch's "CDHash-level deny escalation" theory: once AppleSystemPolicy / syspolicyd / amfid has cached enough deny decisions for the Developer-ID-signed bytes, the deny is keyed on the code directory hash and propagates to any path that contains those bytes. Only an ad-hoc resign (which produces a fresh CDHash) AND a path outside any quarantined directory clears both layers.
Drop-in script for the full fix
For anyone who needs to recover quickly:
# Run AFTER `brew install --cask codex` or `brew upgrade codex` (re-run on every upgrade)set -e
CODEX_BIN=$(ls /opt/homebrew/Caskroom/codex/*/codex-aarch64-apple-darwin | head -1)
cp "$CODEX_BIN" /opt/homebrew/bin/codex-aarch64-apple-darwin
codesign --force -s - /opt/homebrew/bin/codex-aarch64-apple-darwin
xattr -c /opt/homebrew/bin/codex-aarch64-apple-darwin
rm -f /opt/homebrew/bin/codex
ln -sf /opt/homebrew/bin/codex-aarch64-apple-darwin /opt/homebrew/bin/codex
xattr -d com.apple.quarantine /opt/homebrew/Caskroom/codex/*/ 2>/dev/null ||true
codex --version # should print codex-cli <version> and exit 0
This needs to be re-run on every brew upgrade codex because the upgrade replaces the /opt/homebrew/bin/codex symlink to point back into Caskroom and re-quarantines the binary. A Homebrew Cask postflight block in the cask definition would automate this, but the canonical fix is upstream — adding xcrun notarytool submit && xcrun stapler staple to the Codex release pipeline as @g-taki suggested, the same approach astral-sh/uv took in astral-sh/uv#17123.
Incidental debris worth scrubbing (not the cause of the hang, but accumulates because of it)
Independent of the AppleSystemPolicy block, two pieces of state pile up on machines that have hit this repeatedly. They made initial diagnosis noisier because one of them looked superficially like a stale lockfile, which is a classic Rust-CLI hang pattern:
~/.codex/tmp/arg0/codex-arg0*/ and ~/.codex/tmp/path/codex-arg0*/ — codex's per-invocation codex-execve-wrapper and apply_patch shim directories. Codex appears to create them at startup as part of its sandbox setup, but they don't get cleaned up when the process is killed in launch-suspended state. I had six of them, the oldest containing a 2-day-old .lock file.
~/.codex/auth.json.codex-auth.YYYYMMDD-HHMMSS — codex backs up auth on every run but never deletes the backups. 12 files had accumulated over ~4 days of failed launches.
To clean up safely (auth.json itself is preserved):
To be explicit so future readers don't go down the wrong path: the .lock file is not the cause of the hang. The hang is the OS-level AppleSystemPolicy block this issue describes. The lockfile is just an artifact left behind by previously-hung invocations.
Thanks again to everyone in this thread — it is genuinely one of the more useful OSS bug investigations I have come across. Happy to share additional diagnostic output (full sample traces, log show --predicate 'process == "syspolicyd"' excerpts, etc.) if that would help on the OpenAI side.
Adding a current data point from macOS arm64 after the rust-v0.138.0 release.
This is notable because 0.138.0 includes #26252 (ci: sign macOS release artifacts with Azure Key Vault), but the GitHub release artifact still fails local strict code-signing assessment on this machine.
Environment:
macOS: 26.5.1 build 25F80, arm64
Codex Desktop currently installed: 26.602.40724 build 3593
So at least on this machine, the 0.138.0 macOS arm64 release artifact is runnable in a direct terminal smoke test, but is still not accepted by strict codesign / spctl. This looks like the signing/notarization pipeline fix may not yet be reflected in the published single-binary artifact, or the artifact is still missing something Gatekeeper expects.
Activity
etraut-openai commentedon Apr 11, 2026
Thanks for the bug report. Has this worked for you in previous version? I'm trying to determine if this was a regression in 0.120.0 specifically. If you install 0.119.0, does that work for you?
g-taki commentedon Apr 12, 2026
Thanks for looking into this, @etraut-openai.
I did further testing today and the results change the diagnosis significantly:
Version testing:
brew install --cask codex→ hangsSo this is not a regression between versions. Both work fine when downloaded directly.
Root cause (revised):
The issue is the interaction between Homebrew Cask and macOS 26's Gatekeeper:
com.apple.quarantineon the extracted binaryspctl --assess --type executereturnsrejected— the binary is properly signed (Developer ID) but not notarizeddyldeven startsxattr -d com.apple.quarantinedoes not fix it — macOS 26 persists the quarantine state in a system-level database (not just the xattr)Suggested fix:
Submit the release binaries to Apple's notary service (
xcrun notarytool submit). Once notarized, Gatekeeper will allow execution even with quarantine. This would fix Homebrew Cask installs on macOS 26 permanently.Workaround for users:
Use the official install script instead of Homebrew Cask — it downloads directly to
~/.local/bin/without triggering Homebrew's quarantine:curl -fsSL https://github.com/openai/codex/releases/download/rust-v0.120.0/install.sh | shI'll also correct my original issue description — the earlier hypothesis about "obsolete code signature format" was wrong. The signing is fine; the missing piece is notarization.
iwinux commentedon Apr 13, 2026
iwinux commentedon Apr 14, 2026
Interesting. I re-install it via Homebrew today (the same v0.120.0) and it runs without error. Assuming you haven't silently replaced the binary, it might be a glitch at the Apple side?
BTW: you should warn users NEVER run
xattr -d com.apple.quarantinewhen such issue happens :)cuber commentedon Apr 22, 2026
Confirming this still reproduces on codex-cli 0.122.0 / macOS 26 Tahoe (Darwin 25.3) / Apple Silicon, installed via
brew install --cask codex.One correction to the workaround:
cpdoes not stripcom.apple.provenanceon my system — the xattr is still present on the copied file at/tmp. What actually fixes the hang is the ad-hoc resign alone:After this,
codex --versionworks at the original Caskroom path even thoughcom.apple.provenanceis still on the inode. So the trigger seems to be the combination of the original signature + provenance, not the xattr's presence.iwinux commentedon Apr 23, 2026
Here comes the the weird part: it's not 100% reproducible, even with the same macOS version + Codex CLI version:
codexbinary installed viabrew install --cask codexhas the same SHA256.ashwch commentedon Apr 27, 2026
Thanks for the detailed write-up. cc @iwinux since this appears to match your report/workaround closely.
I hit what looks like the same failure mode on
codex-cli 0.125.0, installed via Homebrew Cask, on macOS 26.4.1 / Darwin 25.4.0 arm64.Symptoms:
A
codex exec --json ...process appeared to hang before producing any output.A fresh
/opt/homebrew/bin/codex --versionalso hung.sample <pid> 3showed every sample at_dyld_start; no useful Codex/Rust frames.vmmap -summary <pid>reported:The process had only a tiny memory footprint, no CPU activity, and no child process, so it was not blocked inside Codex agent work.
codesign --verify --strict --verbose=2passed for the executable.spctl --assess --type execute -vvreported:Quarantine details:
com.apple.quarantinewithHomebrew Caskin the value.xattr -lr /opt/homebrew/Caskroom/codex/0.125.0then showed quarantine still present on the cask version directory.xattr -dr com.apple.quarantine /opt/homebrew/Caskroom/codex/0.125.0, the original executable still launched suspended.The strongest datapoint: a byte-identical copy of the same executable ran normally.
Replacing the original cask executable inode with the byte-identical working copy fixed the Homebrew path:
So in this case it was not a Codex runtime hang. The process was created but never resumed before dyld completed. Clearing visible
com.apple.quarantinewas insufficient; creating a new inode for the same signed bytes fixed it. This seems consistent with macOS 26.4.1 / AppleSystemPolicy retaining launch-blocking state for the original Homebrew Cask artifact outside the normal visible xattr path.ashwch commentedon May 6, 2026
(Previous comment removed — posted prematurely before the full fix was identified. This is the corrected version.)
macOS 26.4.1 (25E253), Darwin 25.4.0, ARM64 — Codex v0.128.0 via Homebrew Cask — two separate issues, both triggered by the Cask install path
Following up on #17447 (comment) — the inode-replacement fix alone was not sufficient here. The full fix required both ad-hoc re-signing and moving the binary out of the Caskroom directory tree.
Symptoms (identical to OP)
sample <pid>: every sample at_dyld_startvmmap -summary <pid>:"Process exists but has not started -- it is launched-suspended"spctl --assess --type execute -vv:rejected (the code is valid but does not seem to be an app)What was tried, in order
xattr -d com.apple.quarantineon the binaryxattr -rd com.apple.quarantineon the entire Caskroom treecpbinary to/tmp(fresh inode, clean path)cp+rm+mvto force new inode at original pathbrew reinstall --cask codexcodesign --remove-signature--versioncodesign -s -(ad-hoc sign) + run from/tmp/tmp✅com.apple.quarantine, and binaries placed inside it inherited the launch-suspended behavior/opt/homebrew/bin/+ symlinkWhat actually fixed it
After this,
codex --versionprintscodex-cli 0.128.0and exits 0 normally.Two distinct mechanisms at play
CDHash-level launch-suspension — AppleSystemPolicy caches a deny decision keyed on the binary's code directory hash. Once the Developer ID-signed binary has been blocked, all copies of those bytes are launch-suspended system-wide, regardless of path or inode. This is why
brew reinstall(downloading the same signed bytes) doesn't help.Quarantined directory poisoning — The
com.apple.quarantinexattr on the Caskroom directory (/opt/homebrew/Caskroom/codex/0.128.0/) propagates to any executable placed inside it, re-triggering the launch-suspension even for binaries that work fine from/tmpor/opt/homebrew/bin/.The earlier inode-replacement workaround likely worked because (a) the block hadn't yet escalated to CDHash-level on that machine and (b) the directory quarantine was cleared first. By the time a machine hits exit-137-on-unsigned behavior, both issues need to be addressed.
cossio commentedon May 9, 2026
Reproduces on Codex 0.130.0 — and the SSH/remote case makes it much worse than a typical Gatekeeper prompt
Adding a data point that highlights why this is more severe than a one-time consent dialog:
codex-cli 0.130.0viabrew install --cask codex— same_dyld_starthang,Process exists but has not started -- it is launched-suspended, signed byOpenAI OpCo, LLC (2DC432GLL2)but not notarization-stapled (xcrun stapler validate→ "does not have a ticket stapled to it").brew upgrade, not a fresh install. Every Cask update re-appliescom.apple.quarantineand re-arms the prompt, so this recurs on every release."codex-aarch64-apple-darwin" is an app downloaded from the Internet. Are you sure you want to open it?) is rendered on the local console, where there's no human to dismiss it. From the SSH side,codexsimply hangs forever with no output, no error, and no indication that a UI prompt is the blocker. Diagnosing it requiressample <pid>(everything at_dyld_start) pluslog show --predicate 'process == "syspolicyd"'to even realize Gatekeeper is involved.This effectively bricks
codexon every CI runner, build server, and remote-dev box on macOS 26 until someone physically (or via remote desktop) clicks "Open" —sshalone cannot recover the machine.The proposed fix earlier in this thread — notarizing release binaries with
xcrun notarytool submit— would resolve this cleanly: notarized + stapled binaries don't trigger the first-launch consent dialog, so headless installs via Homebrew Cask would just work.andersongmxde commentedon May 15, 2026
First, thanks to @g-taki for the meticulous original diagnosis and the revised root-cause writeup, to @cuber for the cleaner in-place resign variant, to @ashwch for the comprehensive workaround that actually unblocked me, to @cossio for the most recent confirmation on 0.130.0, and to @etraut-openai for engaging on triage. This thread is the single best resource on the bug.
Still reproducing on Codex CLI 0.130.0 / macOS 26.4.1 Tahoe (build 25E253) as of 2026-05-15 — and on this machine the simpler in-place resign workaround was not sufficient.
Posting an additional data point because the workaround selection seems to be machine-dependent, and the OS-level signature here is identical to what @g-taki and @ashwch already reported. Hopefully this helps anyone (or any AI coding assistant) landing on this issue while trying to figure out why
codexhangs with no output on macOS Tahoe.Environment
codex-cli 0.130.0installed viabrew install --cask codexOpenAI OpCo, LLC (2DC432GLL2)(Developer ID),xcrun stapler validatereports no notarization ticketSymptoms (matching the OP exactly)
codexinvocation hung indefinitely.codex --version,codex --help, evencodex completion zshandcodex completion fish(spawned automatically by shell startup) all hung. Six unkillablecodex-aarch64-apple-darwinprocesses had silently accumulated through the day — every new terminal that loaded zsh/fish completions spawned another doomed instance.ps -axo pid,stat,wchan,etime,pcpu,command: stateS,WCHANempty, 0% CPU, 41+ minutes elapsedsample <pid> 2 -mayDie: 100% of samples at_dyld_start (in dyld) + 0, physical footprint stuck at 112K, peak 112K (i.e. dyld never loaded a single library)lsof -p <pid>: zero TCP sockets, only the codex binary mapped + dyld + redirected stdio. No network reached, no config loaded.vmmap -summary <pid>: "Process exists but has not started -- it is launched-suspended" (matches @ashwch's report)spctl --assess --type execute -vvon the binary:rejected (the code is valid but does not seem to be an app)SIGTERMignored.SIGKILLeventually landed but took several seconds — consistent with the process being suspended in a mach-port wait for an AppleSystemPolicy verdict that never came.If you're an LLM-assisted developer searching for
codex hangs,codex no output,codex --version hangs forever,codex stuck at dyld start macOS Tahoe,brew install cask codex broken,AppleSystemPolicy launched-suspended,OpenAI codex SIGKILL macOS 26,homebrew codex notarization, orcodex completion zsh hangs— yes, this is the issue, and the comments below contain the fix.Workaround comparison on this machine
xattr -d com.apple.quarantineon the binarycp→codesign --force -s -→mvback to CaskroomSignature=adhoc, new Identifiercodex-clean-<sha1>),xattrcleared, butcodex --versionstill timed out at 15s./opt/homebrew/bin/, adhoc-sign there, repoint thecodexsymlink, clear Caskroom dir quarantinecodex --versionreturnscodex-cli 0.130.0in ~1.4s, exit 0.This is consistent with @ashwch's "CDHash-level deny escalation" theory: once
AppleSystemPolicy/syspolicyd/amfidhas cached enough deny decisions for the Developer-ID-signed bytes, the deny is keyed on the code directory hash and propagates to any path that contains those bytes. Only an ad-hoc resign (which produces a fresh CDHash) AND a path outside any quarantined directory clears both layers.Drop-in script for the full fix
For anyone who needs to recover quickly:
This needs to be re-run on every
brew upgrade codexbecause the upgrade replaces the/opt/homebrew/bin/codexsymlink to point back into Caskroom and re-quarantines the binary. A Homebrew Caskpostflightblock in the cask definition would automate this, but the canonical fix is upstream — addingxcrun notarytool submit && xcrun stapler stapleto the Codex release pipeline as @g-taki suggested, the same approachastral-sh/uvtook in astral-sh/uv#17123.Incidental debris worth scrubbing (not the cause of the hang, but accumulates because of it)
Independent of the AppleSystemPolicy block, two pieces of state pile up on machines that have hit this repeatedly. They made initial diagnosis noisier because one of them looked superficially like a stale lockfile, which is a classic Rust-CLI hang pattern:
~/.codex/tmp/arg0/codex-arg0*/and~/.codex/tmp/path/codex-arg0*/— codex's per-invocationcodex-execve-wrapperandapply_patchshim directories. Codex appears to create them at startup as part of its sandbox setup, but they don't get cleaned up when the process is killed in launch-suspended state. I had six of them, the oldest containing a 2-day-old.lockfile.~/.codex/auth.json.codex-auth.YYYYMMDD-HHMMSS— codex backs up auth on every run but never deletes the backups. 12 files had accumulated over ~4 days of failed launches.To clean up safely (
auth.jsonitself is preserved):To be explicit so future readers don't go down the wrong path: the
.lockfile is not the cause of the hang. The hang is the OS-level AppleSystemPolicy block this issue describes. The lockfile is just an artifact left behind by previously-hung invocations.Thanks again to everyone in this thread — it is genuinely one of the more useful OSS bug investigations I have come across. Happy to share additional diagnostic output (full
sampletraces,log show --predicate 'process == "syspolicyd"'excerpts, etc.) if that would help on the OpenAI side.jensenojs commentedon Jun 9, 2026
Adding a current data point from macOS arm64 after the
rust-v0.138.0release.This is notable because
0.138.0includes #26252 (ci: sign macOS release artifacts with Azure Key Vault), but the GitHub release artifact still fails local strict code-signing assessment on this machine.Environment:
26.5.1build25F80,arm6426.602.40724build3593codex-cli 0.137.0-alpha.4rust-v0.138.0 / codex-aarch64-apple-darwin.tar.gzhttps://github.com/openai/codex/releases/download/rust-v0.138.0/codex-aarch64-apple-darwin.tar.gzWhat I tested:
Observed:
completion zshsucceeds and emits completions, but strict signing and Gatekeeper assessment still fail:So at least on this machine, the
0.138.0macOS arm64 release artifact is runnable in a direct terminal smoke test, but is still not accepted by strictcodesign/spctl. This looks like the signing/notarization pipeline fix may not yet be reflected in the published single-binary artifact, or the artifact is still missing something Gatekeeper expects.🐛 install.sh: codex quarantine ハング対策を追加