iOS · build & submit

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:

  1. If the certificate expired, create a new Apple Distribution certificate, install it, and export a fresh .p12 from Keychain Access. Then regenerate every profile that referenced the old one — profiles embed the certificate, so they die with it.
  2. If only the profile expired, open it in Profiles, click Edit, confirm the right certificate is ticked, and download the regenerated file.
  3. 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:

ArtifactLifetimeWhat its expiry blocks
Apple Distribution certificateAbout 3 years Signing anything. Also invalidates every profile embedding it.
Provisioning profileAbout 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.