# Ошибки eas submit iOS: причины и как их исправить

> eas submit падает? Реальные сообщения EAS и App Store Connect, их причины и исправление: ascAppId, API-ключ, соглашение Apple, коды ITMS.

Оригинальная страница: [Ошибки eas submit iOS: причины и как их исправить](https://devoria.fr/ru/blog/eas-submit-ios-errors-fix)
Автор: [Mehdi Azizi](https://devoria.fr/ru/mehdi-azizi)
Опубликовано: 2026-11-04
Последняя правка контента: 2026-11-04


Когда `eas submit --platform ios` падает, сообщение почти всегда подсказывает, куда смотреть. **Либо у тебя неполная конфигурация EAS, либо мешает аккаунт Apple, либо Apple отклоняет бинарник.** Первые два случая исправляются за пару минут, без нового билда. Третий узнаётся по коду ITMS и почти всегда требует нового билда.

Я публикую свои iOS-приложения, включая Solys, TradaZen и Nolera, через Expo и EAS. Сообщения, которые я привожу, скопированы из исходного кода EAS CLI в [официальном репозитории Expo на GitHub](https://github.com/expo/eas-cli), перечитанного 3 ноября 2026 года. Старый форум Expo теперь отправляет в Discord, так что код остаётся самым надёжным источником. Весь путь, от файла `eas.json` до отправки на ревью, описан в статье [EAS Submit iOS: публикация приложения Expo в App Store](https://devoria.fr/ru/blog/eas-submit-ios-publish-expo-app-store). Прочитай её сначала. Здесь мы чиним.

## Что делает eas submit и что ему нужно

Согласно [документации Expo](https://docs.expo.dev/deploy/submit-to-app-stores/), команда отправляет твой файл `.ipa` в App Store Connect. Билд появляется в TestFlight после обработки на стороне Apple, обычно через 10-15 минут. **Она не отправляет приложение на ревью**: это нужно сделать самому в App Store Connect.

[Страница Expo про отправку для iOS](https://docs.expo.dev/submit/ios/) перечисляет три условия:

- **платный аккаунт Apple Developer**, обязательный для любой отправки в App Store;
- **bundle identifier** в `ios.bundleIdentifier`;
- **установленный EAS CLI**, подключённый к твоему аккаунту Expo.

Для отправки без интерактива та же страница добавляет две настройки:

- **`ascAppId`** в профиле `submit` файла `eas.json`, это номер твоей карточки в App Store Connect;
- **API-ключ App Store Connect**, которым управляет EAS или который даёшь ты сам. Как его создать, какую роль дать и как отозвать, разобрано в статье [API-ключ App Store Connect (.p8)](https://devoria.fr/ru/blog/app-store-connect-api-key-p8).

Минимальный профиль занимает несколько строк. Значение выдуманное:

```json
{
  "submit": {
    "production": {
      "ios": {
        "ascAppId": "1234567890"
      }
    }
  }
}
```

Если EAS уже хранит твой API-ключ, этого профиля достаточно. Так у большинства моих приложений.

## Читаем сообщение: три семейства ошибок

Прежде чем искать исправление, найди момент, где команда остановилась. Эта таблица и есть схема, по которой я разбираю каждый сбой.

| Момент сбоя                            | Семейство         | Нужен новый билд? |
| -------------------------------------- | ----------------- | ----------------- |
| До любой отправки                      | Конфигурация EAS  | Нет               |
| Подключение к Apple, создание карточки | Аккаунт Apple     | Нет               |
| После отправки, код ITMS-90xxx         | Бинарник отклонён | Почти всегда      |

Подробности видны на странице сабмита в дашборде Expo. [Expo советует](https://docs.expo.dev/deploy/submit-to-app-stores/) читать там логи и искать блок «Build Annotations», который указывает на частые причины сбоев. В терминале опция `--verbose` всегда выводит логи EAS Submit, согласно [справочнику EAS CLI](https://docs.expo.dev/eas/cli/).

## Ошибки конфигурации EAS

### «Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode.»

Ты запустил команду с `--non-interactive`, например в CI, а в профиле нет `ascAppId`. [Код EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) в этом случае останавливается: он не может ни задать тебе вопрос, ни создать карточку за тебя.

**Исправление: скопируй номер карточки в `ascAppId`.** [Expo объясняет, где его найти](https://github.com/expo/fyi/blob/main/asc-app-id.md): в App Store Connect открой приложение, затем App Information. Это поле Apple ID в разделе General Information, число примерно из десяти цифр. Это не твой Apple e-mail и не bundle identifier.

На Nolera без `ascAppId` команда требовала у меня сессию Apple Developer, которая истекает. С тех пор как номер лежит в `eas.json`, отправка больше ничего не спрашивает.

> Добавляй `ascAppId` до билда, а не после. До SDK 57 [фингерпринт, который считает Expo](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/src/sourcer/Expo.ts), всегда включает `eas.json`. На Vigie, где runtime version следует политике `fingerprint`, добавление этого номера после билда изменило фингерпринт: опубликованное потом обновление так и не дошло бы до установленного билда. Начиная с SDK 58 пресет фингерпринта по умолчанию, `balanced`, игнорирует `eas.json`, согласно [changelog Expo](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/CHANGELOG.md).

### «App Store Connect API Keys cannot be set up in --non-interactive mode.»

В профиле нет ключа, и у EAS нет ни одного ключа, привязанного к твоему приложению. [Expo уточняет](https://docs.expo.dev/submit/ios/): в неинтерактивном режиме команда не может запросить ключ и падает с этим сообщением.

Два варианта исправления:

- **Пусть EAS создаст и хранит ключ.** Один раз запусти `eas credentials --platform ios` в интерактивном режиме на своей машине и дай ему настроить API-ключ App Store Connect для приложения.
- **Подставь свой ключ** в `ascApiKeyPath`, `ascApiKeyIssuerId` и `ascApiKeyId`. Согласно [справочнику eas.json](https://docs.expo.dev/eas/json/), эти три поля принимают переменные окружения, например `$ASC_API_KEY_PATH`.

На моём последнем приложении опция `--auto-submit` хотела Apple ID, чтобы создать ключ для отправки. Я прописал три поля своего ключа в профиль в рабочей копии, которую никогда не коммитил. Потом отправил готовый билд с `--id` и `--non-interactive`.

### «EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter.»

В переменной лежит не пароль приложения, а что-то другое, часто сам пароль от Apple ID. [EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) проверяет этот формат до любой отправки.

Согласно [справке Apple](https://support.apple.com/en-us/102654), пароль приложения создаётся на account.apple.com в разделе App-Specific Passwords при включённой двухфакторной аутентификации. Он отзывается, как только ты меняешь пароль Apple ID. **Expo считает этот способ [менее безопасным, чем API-ключ](https://github.com/expo/fyi/blob/main/apple-app-specific-password.md), который у него используется по умолчанию и рекомендуется.**

## Ошибки аккаунта Apple

### «… agree to the latest Program License Agreement in your developer account.»

Полное сообщение начинается с «You currently don't have access to this membership resource». Сырой ответ Apple может содержать «Unable to process request - PLA Update available». Новые шаги отправки EAS показывают скорее «A required Apple agreement is missing or has expired».

Причина одна: Apple обновила соглашение, и никто его не принял. **Принимать соглашения может только владелец аккаунта, Account Holder**, согласно [таблице ролей Apple](https://developer.apple.com/help/account/access/roles/). [Код EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) просит его зайти на страницу Business в App Store Connect, а затем, если Apple предложит, в свой аккаунт на developer.apple.com. После этого перезапусти команду. Для соглашения о платных приложениях есть отдельный гайд: [Paid Apps Agreement в App Store Connect](https://devoria.fr/ru/blog/paid-apps-agreement-statuses-w-8ben-first-payment).

### «App Store Connect rejected the API authentication credentials.»

Apple ответила ошибкой 401, `NOT_AUTHORIZED`. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) называет три причины: ключ больше не активен, ключ от другого аккаунта App Store Connect, или неверный Key ID, содержимое ключа или Issuer ID.

Проверь оба идентификатора в App Store Connect, меню Users and Access, вкладка Integrations. Согласно [Apple](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests), Issuer ID показан вверху страницы, а Key ID в списке активных ключей. **Отозванный ключ никогда не активируется снова.** [Apple показывает его](https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys) 30 дней в разделе Revoked: нужно сгенерировать новый.

### «App Store Connect app for application identifier … was not found.»

Карточку, на которую указывает `ascAppId`, не видно с твоим ключом. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiUtils.ts) просит проверить этот номер и убедиться, что у ключа есть доступ к приложению в нужном аккаунте. Он даже выводит несколько приложений, видимых с этим ключом. В инструментах отправки Apple та же проблема выглядит как «No suitable application records were found».

Чаще всего встречаются три причины, две из них описаны в [этой ветке форумов Apple](https://developer.apple.com/forums/thread/106806):

- **Карточки не существует.** Создай её в App Store Connect или убери `ascAppId`, чтобы команда создала её сама.
- **Номер из другого аккаунта.** Ты скопировал `ascAppId` другой команды или другого проекта.
- **У пользователя нет доступа к приложению.** App Manager или Developer могут быть ограничены отдельными приложениями. А ключ команды [имеет доступ ко всем приложениям](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api) аккаунта.

### «… is not available to team» или «… is not available to provider»

Это сообщение появляется, когда EAS создаёт карточку за тебя, потому что нет `ascAppId`. Bundle identifier уже занят другой командой. [EAS просит](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/credentials/ios/appstore/ensureAppExists.ts) поменять его в конфигурации приложения и перезапустить.

### «App name "…" is already taken. Using generated name "…"»

Это не сбой. Если название уже занято в App Store, EAS добавляет шесть случайных символов и пробует снова, до пяти раз. Переименуешь карточку потом в App Store Connect. Чтобы этого избежать, заполни `appName` и `language` в профиле до первой отправки: без `language` [основной язык будет `en-US`](https://docs.expo.dev/eas/json/).

## Ошибки бинарника: коды ITMS

После отправки Apple обрабатывает билд. Если она его отклоняет, в логе будет один или несколько кодов ITMS. Вот те, которые [шаг отправки EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/functions/uploadToAsc.ts) распознаёт и расшифровывает:

| Код ITMS                   | Что отклоняет Apple                      | Исправление            |
| -------------------------- | ---------------------------------------- | ---------------------- |
| 90189                      | Номер билда уже занят                    | `autoIncrement`        |
| 90062, 90186, 90478        | Версия закрыта или уже превышена         | Поднять `version`      |
| 90683                      | Нет строки с целью доступа               | `ios.infoPlist`        |
| 90725                      | Слишком старый iOS SDK                   | Образ iOS или SDK Expo |
| 90054, 90055               | Bundle не совпадает с нужной карточкой   | Исправить `ascAppId`   |
| 90022, 90023, 90391, 90713 | Иконки отсутствуют или объявлены неверно | Проверить иконки       |
| 90771                      | Нет идентификаторов фоновых задач        | `ios.infoPlist`        |

Три уточнения из этих сообщений:

- **Номер билда уникален в рамках версии.** Для 90189 EAS рекомендует `"autoIncrement": true` в `eas.json`. Всё разобрано в статье [номер билда и версия](https://devoria.fr/ru/blog/app-store-connect-build-number-version).
- **Для 90725** EAS советует выбрать более новый образ iOS в `eas.json`, а при необходимости перейти на поддерживаемый SDK Expo.
- **Для 90771**: твой Info.plist объявляет фоновый режим `processing`, но не ключ `BGTaskSchedulerPermittedIdentifiers`.

Кроме 90054 и 90055, где достаточно указать нужную карточку или другой билд, **исправление затрагивает бинарник: собери билд заново и отправь его снова.** Для двух кодов есть отдельные гайды: [ITMS-90683 с Expo](https://devoria.fr/ru/blog/itms-90683-missing-purpose-string-expo) и [ITMS-90725](https://devoria.fr/ru/blog/itms-90725-sdk-version-issue-expo).

В конце сентября 2026 года билд Solys отклонили при доставке с ITMS-90683. Я удалил строку с целью доступа к фото, пока чистил файл конфигурации. Solys не использует фото, но одна библиотека в проекте вызывает Photos API в iOS. **Apple анализирует бинарник, а не реальное использование:** с тех пор я никогда не удаляю эти строки.

Статус Missing Compliance, кстати, не ошибка отправки. Не хватает твоей декларации о шифровании, она описана в [гайде по публикации через EAS](https://devoria.fr/ru/blog/eas-submit-ios-publish-expo-app-store).

## Мой чек-лист перед каждой отправкой

- `ascAppId` есть в профиле `submit` и добавлен до билда.
- API-ключом управляет EAS, или три его поля указывают на `.p8`, который лежит вне репозитория.
- Account Holder принял последние соглашения в App Store Connect.
- `autoIncrement` включён вместе с `"appVersionSource": "remote"`, что [Expo рекомендует](https://docs.expo.dev/build-reference/app-versions/) начиная с EAS CLI 12.
- `version` выше последней одобренной версии.
- У каждого чувствительного API в бинарнике есть строка с целью доступа.
- Для нового приложения `appName` и `language` заполнены до первой отправки.

## Как отправить первое приложение и не застрять

Команда всего лишь один из шагов. [iOS & Android Kit](https://devoria.fr/ru/kits/ios) построен на стартовом коде моих приложений, включая подписки, и ведёт тебя в App Store за четыре шага, в твоём темпе.

Если готовишь первый релиз, [пройди бесплатную диагностику](https://devoria.fr/ru/diagnostic): она покажет, что на самом деле тебя тормозит, и пришлёт мой чек-лист против отказов Apple. Про карточку, скриншоты и проверку подробно, шаг за шагом, рассказано на странице [публикация приложения в App Store](https://devoria.fr/ru/expertise/publish-app-on-app-store).

## Частые вопросы

### Почему eas submit падает только в CI?

В режиме `--non-interactive` команда ничего не может у тебя спросить. Ей нужен `ascAppId` в профиле и API-ключ, уже привязанный к приложению, или три его поля в `eas.json`. На твоей машине она бы задала эти вопросы.

### Нужно ли пересобирать билд после ошибки eas submit?

Только если Apple отклоняет бинарник с кодом ITMS. Исключение: при ITMS-90054 и 90055 билд был нацелен не на ту карточку, достаточно отправить его на правильную. Ошибки конфигурации и аккаунта исправляются в `eas.json`, в App Store Connect или в аккаунте Apple. Потом отправляешь тот же билд, например с `--latest` или `--id`.

### Где смотреть логи отправки EAS Submit?

На странице сабмита в дашборде Expo. Expo советует читать там логи и блок «Build Annotations». В терминале добавь `--verbose`, чтобы логи выводились всегда.

### Можно ли использовать eas submit с бесплатным аккаунтом Apple?

Нет. Expo требует платный аккаунт Apple Developer для отправки приложения в App Store. Бесплатный аккаунт позволяет тестировать на своём iPhone, но не пользоваться App Store Connect.

### Какую роль дать API-ключу для eas submit?

В гайде Expo ключу дают роль Admin. Согласно таблице ролей Apple, отправка билдов доступна также ролям App Manager и Developer. Мои билды Expo работают с ключом команды с ролью App Manager. Генерировать ключ команды могут только Account Holder и Admin.

### Что значит «Increment Build Number» в EAS?

Apple отклонила билд с кодом ITMS-90189: такой номер билда уже существует для этой версии. Включи `"autoIncrement": true` в `eas.json` или подними `ios.buildNumber`, затем собери билд заново.


## Твой проект

[Review Kit](https://devoria.fr/ru/kits/app-review): Мой чек-лист для ревью в App Store, исправленные отказы Apple, чек-лист для Google Play и три скилла для Claude Code. 55 $.

[iOS & Android Kit](https://devoria.fr/ru/kits/ios): Создай своё приложение для iPhone и Android с Claude Code: стартовый код моих приложений, путь до публикации в сторах и все киты. 109 $.

[Диагностика: что отделяет тебя от твоего iPhone-приложения](https://devoria.fr/ru/diagnostic): 7 вопросов, 60 секунд: ты узнаешь, что на самом деле мешает тебе опубликовать iPhone-приложение, получишь путь из 4 этапов и подходящий тебе кит.
