Your provisioning profile or distribution certificate has expired
The provisioning profile is expired Your distribution certificate has expired
The short answer
Nothing has happened to your shipped app. Users are unaffected, downloads continue, and the version in the App Store keeps working. Provisioning profiles and distribution certificates are checked when you build and submit, not when someone runs your app. You have lost the ability to ship an update, not the app.
Renew in this order:
- If the certificate expired, create a new Apple Distribution
certificate, install it, and export a fresh
.p12from Keychain Access. Then regenerate every profile that referenced the old one — profiles embed the certificate, so they die with it. - If only the profile expired, open it in Profiles, click Edit, confirm the right certificate is ticked, and download the regenerated file.
- Replace the file in your project and in any CI secret that holds a base64 copy of it. A stale secret is the usual reason this appears fixed locally and still fails in CI.
Why this happens
Three different lifetimes are in play, which is why this catches people who thought they had just dealt with it:
| Artifact | Lifetime | What its expiry blocks |
|---|---|---|
| Apple Distribution certificate | About 3 years | Signing anything. Also invalidates every profile embedding it. |
| Provisioning profile | About 1 year | Building for the App ID it covers. |
App Store Connect API key (.p8) | No expiry | Nothing — it lives until revoked. |
The profile is the one that bites, because a year is exactly long enough to forget and exactly short enough to recur. And it always surfaces at the worst moment: you do not build a release every day, so the first build after expiry is usually the urgent one.
Reading the dates before they matter
Both dates are sitting in files you already have. For the profile:
security cms -D -i profile.mobileprovision | grep -A1 ExpirationDate
For the certificate inside your .p12:
openssl pkcs12 -in dist.p12 -clcerts -nokeys -passin pass:YOURPASSWORD \
| openssl x509 -noout -enddate
If OpenSSL 3 refuses your .p12, add -legacy — Keychain Access
still exports with ciphers OpenSSL 3 disabled by default.
Revocation is not the same as expiry
Worth knowing before you click anything in the developer console: an expired certificate stops working on its expiry date and can simply be replaced. A revoked certificate stops working immediately, everywhere, including for every teammate and every CI job using it. If you are only trying to renew, create the new certificate first and leave the old one alone until the new pipeline is proven.
Catching it before you build
Expiry is the failure mode that most rewards being told in advance, because the fix is easy and the timing is always terrible. leas creds reads both dates back out of the files themselves, soonest first, so there is nothing to keep in sync by hand:
▸ Credentials
! Provisioning profile 2026-09-09 19 days left
Kaya App Store
✓ Distribution certificate 2027-10-07 412 days left
Apple Distribution: Kaya Labs
✓ Upload keystore 2051-12-11 9243 days left
alias upload
! 1 expiring within 30 days. Renew before it bites.Set up leas in 10 minutesFree, MIT licensed, and it never receives your signing keys.
If that didn’t fix it
- Renewed and still refused. Regenerating a profile does not re-download it. Confirm the file on disk is the new one by checking its expiry, not its filename.
- Xcode is using a cached copy. Installed profiles live in
~/Library/MobileDevice/Provisioning Profiles/keyed by UUID. Deleting the old file there forces a fresh read. - The certificate expired too, and you only renewed the profile. The profile will be issued happily against an expired certificate. Check both dates — the commands are above.