"…can't be opened because Apple cannot check it for malicious software"
What the user sees
When someone downloads your app, Gatekeeper shows: "YourApp" can't be opened because Apple cannot check it for malicious software. This is different from an unsigned-app warning — it means the signature is fine, but the notarization step is missing or invisible.
Why it happens
- The build was signed with a Developer ID cert but never submitted for notarization.
- It was notarized, but you never ran
stapler staple, so the ticket isn't attached — machines that are offline or that got the file via download (quarantine bit set) can't confirm it. - For plugins shipped in a zip: the ticket was stapled to the archive instead of the individual bundles. A zip can't hold a staple.
How to fix it
- Submit the signed app (zipped) to the notary service and wait:
ditto -c -k --keepParent YourApp.app YourApp.zip xcrun notarytool submit YourApp.zip --keychain-profile "AC" --wait
- When it returns
Accepted, staple the ticket to the bundle (not the zip):xcrun stapler staple YourApp.app
- Shipping bare plugins in a zip? Staple each
.vst3/.componentbundle individually, then zip them for distribution.
How to confirm it's fixed
spctl -a -vvv -t exec YourApp.app # expect: accepted, source=Notarized Developer ID xcrun stapler validate YourApp.app # expect: The validate action worked!
Test on a clean Mac, ideally with the quarantine bit set, since that's what your users experience after downloading.
Upload your build and get the exact reason it passes or fails Gatekeeper — including the zip-staple mistake.
Check my installer →A note on the first notarization
A brand-new Apple account's first notarization can take hours (an anti-abuse review); later ones are usually minutes. If your debut release looks stuck, it's likely this — not your build.
Preventing it entirely
SignetKeys notarizes and staples every release as part of one pipeline — stapling the individual bundles for plugin zips — and delivers the finished, stapled artifact back to your CI. The RFC 3161 timestamp and stapled ticket mean your users never need to contact anyone to open your app. See how it works →