A tester messages you: “Your beta won’t open anymore — it says ‘This beta has expired.’” You open App Store Connect → TestFlight → Builds, and the build that’s been running smoothly for two months now shows status Expired. Some testers can still launch (the build is cached on their device for a few days post-expiration depending on iOS version), but new installs and many existing ones are blocked. Your entire external test cycle just paused, and you have no way to “extend” the expired build.
TestFlight builds have a fixed 90-day lifetime from the upload date. Apple enforces it strictly; no per-account exceptions, no extensions. The fix isn’t to revive the dead build — it’s to push a fresh build with the same or higher version that takes its place in the testers’ TestFlight app.
Common causes
Ordered by hit rate.
1. Build hit the 90-day TestFlight lifetime cap
The 90-day clock starts at upload, not at first install. After 90 days, Apple marks the build Expired in App Store Connect and TestFlight app rejects launches with “This beta has expired.” There is no extension mechanism.
How to spot it: App Store Connect → TestFlight → Builds. Look at the build’s upload date. If it’s 85+ days ago, expiration is imminent or has happened.
2. No newer build was uploaded before expiration
You shipped one build for a long beta cycle and never rotated. Day 91 hits, the build expires, testers are locked out, and you have no fallback build ready to go.
How to spot it: Check the count of “available” builds in your TestFlight Builds tab. If you only have one build and it’s old, you’re at risk.
3. Old build was kept active while newer one was withdrawn
You uploaded a newer build, made it available to testers, then discovered a regression and removed it from the group. Testers fall back to the older build, which then expires while you’re still iterating on the fix.
How to spot it: Activity log shows recent “withdrawn” actions. If the only “active” build now is older than 60 days, you have a rotation gap.
4. New build uploaded but never attached to the tester group
You uploaded a fresh build, it processed, sits in Builds as “Ready to Submit,” but you forgot to add it to the external testing group or send to internal testers. The old build expires; testers can’t see the new one.
How to spot it: In TestFlight → your group, check the list of builds attached. If the latest build is missing from the group, attach it.
5. New build awaiting Beta App Review
You uploaded promptly, but the new build is queued for Beta App Review. Old build expires during the wait; testers see neither.
How to spot it: New build status is “Waiting for Beta App Review.” Use internal testing as a stopgap, or wait out Beta review.
Information to collect
- Upload date of the expired build (90-day calculation).
- Version (
CFBundleShortVersionString) and build number (CFBundleVersion) of the expired build. - Status of any pending builds (Processing, Waiting for Review, etc.).
- Group attachment for both expired and pending builds.
- Tester complaint timestamps if you need to communicate fix timing.
Shortest path to fix
Step 1: Identify the right “next” build
In App Store Connect → TestFlight → Builds, look for:
- A processed build at version ≥ the expired one’s version, with a higher build number.
- If none exists, you need to upload a new build.
You cannot reactivate the expired build; only replacement works.
Step 2: Build a fresh archive
In Xcode:
- Bump
CFBundleVersion(e.g.,47→48) — required because the old (47) build is still on Apple’s records. - Optionally bump
CFBundleShortVersionStringif this is a real feature update. - Product → Clean Build Folder.
- Product → Archive (Generic iOS Device).
Or via xcodebuild:
agvtool next-version -all # bump build number
xcodebuild -workspace Acme.xcworkspace -scheme Acme \
-archivePath build/Acme.xcarchive archive
xcodebuild -exportArchive -archivePath build/Acme.xcarchive \
-exportPath build/ipa -exportOptionsPlist exportOptions.plist
xcrun altool --upload-app -f build/ipa/Acme.ipa \
-t ios -u "$ASC_USER" -p "@keychain:ASC_PASSWORD"
Step 3: Wait for processing
Apple processes the build (typically 10-60 minutes). Status moves through “Processing” → “Ready to Submit” (or “Ready to Test” once attached and approved).
# Optional: monitor via App Store Connect API
curl -H "Authorization: Bearer $JWT" \
"https://api.appstoreconnect.apple.com/v1/builds?filter[app]=$APP_ID&sort=-uploadedDate" \
| jq '.data[0].attributes.processingState'
Step 4: Submit for Beta App Review (if external)
If this is a new version (e.g., 2.8 vs the expired 2.7), the first build of the new version needs Beta App Review. Same version + new build number usually does not need re-review (auto-approves).
In App Store Connect → TestFlight → External Testing → your group → Build → Submit for Beta App Review.
Step 5: Attach to tester groups
Once Ready to Test:
- TestFlight → External Testing → your group → ”+” → select the new build.
- TestFlight → Internal Testing → ”+” → select the new build (no review needed).
Step 6: Notify testers
App Store Connect → TestFlight → External Testing → your group → “Notify Testers.” This sends an email to the tester list with a deep link to update.
Write release notes for testers; this is the “What’s New for testers” field. Include any guidance specific to the replacement (e.g., “Please update — previous build expired”).
How to confirm the fix
- The expired build’s status remains “Expired” but the new build shows “Ready to Test” or “Available.”
- Testers who update via TestFlight see the new build’s release notes.
- Cold-install on a fresh device using the TestFlight invite link installs the new build.
- The new build’s expiration date (visible in App Store Connect) is 90 days from its upload date.
If it still fails
- If the new build doesn’t appear for testers, verify it’s attached to the right group and Ready to Test (not still Waiting for Review).
- Have testers force-refresh TestFlight: kill the app, reopen; or sign out and sign back in to TestFlight.
- Check that testers are on the right group; testers in a group that didn’t get the new build attached still see the old (expired) one.
- If Beta review is unusually slow on this replacement, see Beta App Review slow.
Prevention
- Calendar reminder ~80 days after every upload for any long-running beta cycle.
- Maintain a “rotation” rhythm: ship a fresh TestFlight build at least every 60 days, even if there are minimal code changes.
- Always have at least one build under 60 days old attached to active external groups.
- Bump the build number every meaningful test cycle so rolling forward is mechanical.
- Document your TestFlight rotation in a
BETA.mdso the responsibility doesn’t sit only with one person.
Related reading
- TestFlight build stuck in Processing
- New build uploaded but not appearing
- TestFlight external tester no invite
- Beta App Review taking too long
Tags: #Troubleshooting #App Store #App review #TestFlight #Build expired