App Store · 4 min read

TestFlight build not showing for testers? It is stuck at Missing Compliance.

The upload worked. The build says VALID. Nobody can install it. Here is the one Info.plist key that is usually to blame, and the second check to run if it is not.

What you see

You upload a build. It processes and App Store Connect shows it as VALID. Then nothing happens. Testers never get an email. The TestFlight app shows no new build. Nothing on the build page explains why.

If you look closely at the TestFlight tab, the build may carry a small "Missing Compliance" label. If you read the build through the App Store Connect API, its state is MISSING_EXPORT_COMPLIANCE. From the outside it looks exactly like a failed upload.

Why it happens

Apple asks one question of every build: does this app use non-exempt encryption? Until that question is answered, the build cannot be distributed to anyone. It just sits there.

Apple asks the question for every single build unless the app answers it up front in Info.plist. So if you answered it by hand last time, you will hit the same wall on the next upload.

The fix, step by step

Step 1. Confirm this is the problem. Open the build in App Store Connect under TestFlight and look for "Missing Compliance". Or read the build from the API and check its state. If it says MISSING_EXPORT_COMPLIANCE, keep going.

Step 2. Decide your answer. False is correct when the only crypto in your app is HTTPS to your own backend. That covers most apps that call an API and show data. If your app really does use non-exempt encryption, do not answer false. Answer Apple's export compliance questionnaire instead.

Step 3. Unblock the build you already uploaded. You can answer the question in the App Store Connect UI. If you script releases, patch the build directly:

PATCH https://api.appstoreconnect.apple.com/v1/builds/{BUILD_ID}
Content-Type: application/json

{
  "data": {
    "type": "builds",
    "id": "BUILD_ID",
    "attributes": { "usesNonExemptEncryption": false }
  }
}

Once that is set, the build can be distributed.

Step 4. Fix it for every future build. Add the key to Info.plist so each build answers the question at build time:

<key>ITSAppUsesNonExemptEncryption</key>
<false/>

In an Expo project, put it under ios.infoPlist in app.json:

{
  "expo": {
    "ios": {
      "infoPlist": { "ITSAppUsesNonExemptEncryption": false }
    }
  }
}

Step 5. If testers still see nothing, check the group. Compliance is the first gate. The second is whether the build is attached to your tester group. Some CI setups, Codemagic included, upload and submit to TestFlight but never add the build to your internal group. After the build reaches VALID, attach it:

POST /v1/betaGroups/{GROUP_ID}/relationships/builds
{"data":[{"type":"builds","id":"BUILD_ID"}]}

Then verify from the group side with GET /v1/betaGroups/{GROUP_ID}/builds. Do not trust the build side endpoint GET /v1/builds/{id}/betaGroups. It can report false negatives.

One exception. An internal group with automatic distribution turned on gets every processed build by itself. If you try to attach a build to it, Apple returns 422 "Cannot add internal group to a build". That is expected. In that case judge success by the build reaching VALID and by what testers see in the TestFlight app.

How to prevent it

Related traps

Field Notes

This fix is one of 228 in Field Notes: What Broke and How We Fixed It.

Every entry follows the same pattern: the symptom you see, the real cause, the fix that worked, and the rule that stops it coming back. App Store, Google Play, Capacitor, Netlify, Supabase, Stripe, n8n and more.

Get Field Notes

Building a lot? The Builder Bundle has Field Notes plus the launch playbook, the prompt book and the Claude Code skills kit. See the bundle.

Related fixes

Keep reading.