Code signing errors › hardened runtime not enabled
"The executable does not have the hardened runtime enabled"
Short answer: Apple's notary service rejects any binary
signed without the hardened runtime. Re-sign every executable, framework,
and plugin with
--options runtime (and --timestamp),
signing inside-out, then resubmit. This appears in the notarization log, not
at codesign time.
Where you see it
In the notary log JSON returned by notarytool, per offending
binary:
{
"severity": "error",
"message": "The executable does not have the hardened runtime enabled.",
"path": "YourApp.zip/YourApp.app/Contents/MacOS/helper"
}
Why it happens
- A
codesignstep omitted--options runtime. - The outer app was signed with the hardened runtime but an embedded
helper, framework, or plugin was signed without it — the
pathin the log points at the exact object. - A prebuilt third-party framework shipped unsigned or without the runtime and wasn't re-signed.
How to fix it
- Re-sign every Mach-O object with the hardened runtime, inside-out:
codesign --force --options runtime --timestamp \ --sign "Developer ID Application: Your Co (TEAMID)" \ path/to/each/framework-or-helper codesign --force --options runtime --timestamp \ --sign "Developer ID Application: Your Co (TEAMID)" \ YourApp.app
- If your code needs specific capabilities (JIT, DYLD env vars, audio input), add the matching hardened-runtime entitlements rather than dropping the runtime.
- Resubmit to the notary service and poll to completion:
xcrun notarytool submit YourApp.zip --keychain-profile "AC" --wait
How to confirm it's fixed
codesign -dvvv YourApp.app | grep flags # expect: flags=0x10000(runtime)
Every embedded binary must show the runtime flag, not just the
outer bundle.
Find every binary missing the runtime — free
Upload your build and get a per-object report of what's signed, hardened, timestamped, and notarized.
Check my installer →Preventing it entirely
The hardened runtime is a flag that's easy to forget on one nested object
out of dozens. SignetKeys applies
--options runtime --timestamp to every object it signs, as a
non-negotiable default in a fixed pipeline — so a single forgotten flag can't
fail your notarization. See how it works →