eas submit iOS errors: common causes and fixes
By Mehdi Azizi
Published , 10 min
eas submit failing? The real EAS and App Store Connect messages, their cause and fix: ascAppId, API key, Apple agreement, ITMS codes.
When eas submit --platform ios fails, the message almost always tells you where to look. Either your EAS configuration is incomplete, your Apple account is blocking, or Apple is rejecting the binary. The first two cases take a few minutes to fix, with no new build. You can spot the third by its ITMS code, and it almost always needs a new build.
I publish my iOS apps, including Solys, TradaZen and Nolera, with Expo and EAS. The messages quoted here are copied from the EAS CLI source code, on Expo's official GitHub repo, reviewed on November 3, 2026. Expo's old forum now redirects to Discord, so the code remains the most reliable source. For the full walkthrough, from the eas.json file to submitting for review, read EAS Submit iOS: publish an Expo app on the App Store first. Here, we fix things.
What eas submit does, and what it needs
According to Expo's documentation, the command uploads your .ipa file to App Store Connect. The build shows up in TestFlight once Apple has processed it, usually 10 to 15 minutes. It does not submit your app for review: you still do that in App Store Connect.
Expo's iOS submission page lists three prerequisites:
- a paid Apple Developer account, required for any upload to the App Store;
- the bundle identifier in
ios.bundleIdentifier; - EAS CLI installed and logged in to your Expo account.
To submit without any interaction, the same page adds two settings:
ascAppIdin thesubmitprofile ofeas.json, the number of your App Store Connect app record;- an App Store Connect API key, managed by EAS or provided by you. Creating it, its role and revoking it are covered in App Store Connect API key (.p8).
The minimal profile fits in a few lines. The value is fake:
{
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890"
}
}
}
}
If EAS already stores your API key, this profile is enough. That's the case for most of my apps.
Reading the message: three families of errors
Before looking for the fix, find the moment the command stops. This table is the grid I use for every failure.
| When it fails | Family | New build? |
|---|---|---|
| Before anything is uploaded | EAS configuration | No |
| Connecting to Apple, creating the record | Apple account | No |
| After the upload, ITMS-90xxx code | Binary rejected | Almost always |
The details are on the submission page, in the Expo dashboard. Expo recommends reading the logs there and looking for the "Build Annotations" bubble, which flags common failure causes. In the terminal, the --verbose flag always prints the EAS Submit logs, according to the EAS CLI reference.
EAS configuration errors
"Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode."
You ran the command with --non-interactive, in CI for example, and your profile doesn't contain ascAppId. The EAS CLI code stops there: it can't ask you anything, and it can't create the record for you.
Fix: copy your record's number into ascAppId. Expo shows where to find it: in App Store Connect, open your app, then App Information. It's the Apple ID field, under General Information, a number of about ten digits. It's not your Apple email address, and it's not your bundle identifier.
On Nolera, without ascAppId, the command asked me for an Apple Developer session, which expires. Since the number has been in eas.json, the submission doesn't ask for anything.
Add
ascAppIdbefore the build, not after. Up to SDK 57, the fingerprint computed by Expo always includeseas.json. On Vigie, whose runtime version follows thefingerprintpolicy, adding this number after a build changed the fingerprint: an update published afterward would never have reached the installed build. Since SDK 58, the default fingerprint preset,balanced, ignoreseas.json, according to Expo's changelog.
"App Store Connect API Keys cannot be set up in --non-interactive mode."
Your profile doesn't contain a key, and EAS has none attached to your app. Expo spells it out: in non-interactive mode, the command can't ask you for a key, so it fails with this message.
Two possible fixes:
- Let EAS create and store the key. Run
eas credentials --platform iosonce in interactive mode, on your machine, and let it set up an App Store Connect API key for your app. - Bring your own key in
ascApiKeyPath,ascApiKeyIssuerIdandascApiKeyId. According to the eas.json reference, these three fields accept environment variables, like$ASC_API_KEY_PATH.
On my latest app, the --auto-submit flag wanted an Apple ID to create its submission key. I put the three fields of my own key in the profile of my working copy, never committed. Then I submitted the finished build with --id and --non-interactive.
"EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter."
The variable contains something other than an app-specific password, often your actual Apple password. EAS CLI checks this format before uploading anything.
According to Apple's support page, you generate an app-specific password on account.apple.com, under App-Specific Passwords, with two-factor authentication turned on. It's revoked as soon as you change your Apple account password. Expo considers this method less secure than the API key, which is its default and recommended method.
Apple account errors
"… agree to the latest Program License Agreement in your developer account."
The full message starts with "You currently don't have access to this membership resource". On Apple's side, the raw response may contain "Unable to process request - PLA Update available". Recent EAS submission steps show "A required Apple agreement is missing or has expired" instead.
The cause is the same: Apple updated an agreement, and nobody accepted it. Only the account owner, the Account Holder, can accept agreements, according to Apple's roles table. The EAS code tells them to go through the Business page in App Store Connect, then, if Apple prompts for it, through their account on developer.apple.com. Then run the command again. The paid apps agreement has its own guide: Paid Apps Agreement in App Store Connect.
"App Store Connect rejected the API authentication credentials."
Apple answered with a 401 error, NOT_AUTHORIZED. EAS lists three causes: a key that's no longer active, a key from another App Store Connect account, or a wrong Key ID, key content or Issuer ID.
Check both identifiers in App Store Connect, under Users and Access, Integrations tab. According to Apple, the Issuer ID is shown at the top of the page, and the Key ID in the list of active keys. A revoked key can never be reactivated. Apple shows it for 30 days under Revoked: you need to generate a new one.
"App Store Connect app for application identifier … was not found."
The record targeted by ascAppId can't be found with your key. EAS asks you to check that number, and to make sure the key has access to the app in the right account. It even lists a few apps visible with that key. With Apple's upload tools, the same problem shows up as "No suitable application records were found".
Three causes come up, two of them noted in this Apple forums thread:
- The record doesn't exist. Create it in App Store Connect, or remove
ascAppIdso the command creates it. - The number comes from another account. You copied the
ascAppIdfrom another team, or another project. - The user doesn't have access to the app. An App Manager or a Developer can be limited to specific apps. A team key, on the other hand, has access to every app in the account.
"… is not available to team" or "… is not available to provider"
This message shows up when EAS creates the record for you, because there's no ascAppId. The bundle identifier is already taken by another team. EAS asks you to change it in your app config, then run it again.
"App name "…" is already taken. Using generated name "…""
This isn't a failure. When the name is already taken on the App Store, EAS adds six random characters and tries again, up to five times. You'll rename the record later in App Store Connect. To avoid it, set appName and language in the profile before the first submission: without language, the primary language defaults to en-US.
Binary errors: ITMS codes
After the upload, Apple processes the build. If it rejects it, the log cites one or more ITMS codes. Here are the ones the EAS upload step recognizes and translates:
| ITMS code | What Apple rejects | Fix |
|---|---|---|
| 90189 | Build number already used | autoIncrement |
| 90062, 90186, 90478 | Version closed or already superseded | Bump version |
| 90683 | Missing purpose string | ios.infoPlist |
| 90725 | iOS SDK too old | iOS image or Expo SDK |
| 90054, 90055 | Bundle doesn't match the target record | Fix ascAppId |
| 90022, 90023, 90391, 90713 | Icons missing or declared wrong | Review the icons |
| 90771 | Background task identifiers missing | ios.infoPlist |
Three notes from these messages:
- The build number is unique per version. For 90189, EAS recommends
"autoIncrement": trueineas.json. It's all in build number and version. - For 90725, EAS suggests picking a newer iOS image in
eas.json, and if needed moving to a supported Expo SDK. - For 90771, your Info.plist declares the
processingbackground mode, but not theBGTaskSchedulerPermittedIdentifierskey.
Except for 90054 and 90055, where you just need to target the right record or another build, the fix touches the binary: make a new build, then submit it again. Two codes have their own guide: ITMS-90683 with Expo and ITMS-90725.
At the end of September 2026, a Solys build was rejected on delivery for ITMS-90683. I had removed a photos purpose string while cleaning up the config file. Solys doesn't use photos, but a library in the project calls the iOS Photos API. Apple analyzes the binary, not actual usage: since then, I never remove those strings.
The Missing Compliance status, on the other hand, isn't a submission error. Your encryption declaration is missing, as explained in the EAS publishing guide.
My checklist before every submission
ascAppIdis in thesubmitprofile, added before the build.- The API key is managed by EAS, or its three fields point to a
.p8stored outside the repo. - The Account Holder has accepted the latest agreements in App Store Connect.
autoIncrementis on, with"appVersionSource": "remote", recommended by Expo since EAS CLI 12.- The
versionis higher than the last approved version. - Every sensitive API in the binary has its purpose string.
- For a new app,
appNameandlanguageare set before the first submission.
Submitting your first app without getting stuck
The command is just one step. The iOS & Android Kit starts from the Starter Code of my apps, subscriptions included, and walks you through four steps to the App Store, at your own pace.
If you're preparing your first release, take the free diagnostic: it tells you what's really holding you back and sends you my Apple anti-rejection checklist. For the listing, screenshots and approval, the page publish an app on the App Store covers every step.
Frequently asked questions
Why does eas submit only fail in CI?
In --non-interactive mode, the command can't ask you anything. It needs ascAppId in the profile and an API key already attached to the app, or its three fields in eas.json. On your machine, it would have asked you those questions.
Do I need a new build after an eas submit error?
Only if Apple rejects the binary, with an ITMS code. Exception: for ITMS-90054 and 90055, the build targeted the wrong record, so you just submit it again to the right one. Configuration and account errors are fixed in eas.json, in App Store Connect or in your Apple account. Then you submit the same build again, for example with --latest or --id.
Where can I see the logs of an EAS Submit upload?
On the submission page, in the Expo dashboard. Expo recommends reading the logs there and the "Build Annotations" bubble. In the terminal, add --verbose to always print the logs.
Can I use eas submit with a free Apple account?
No. Expo requires a paid Apple Developer account to submit an app to the App Store. The free account lets you test on your own iPhone, not use App Store Connect.
What role should the API key have for eas submit?
Expo's guide gives the key the Admin role. According to Apple's roles table, uploading builds is also open to the App Manager and Developer roles. My Expo builds run with a team key that has the App Manager role. Only the Account Holder and Admins can generate a team key.
What does "Increment Build Number" mean in EAS?
Apple rejected the build with code ITMS-90189: that build number already exists for this version. Turn on "autoIncrement": true in eas.json, or bump ios.buildNumber, then make a new build.

