ITMS-90034: как исправить «Missing or invalid signature»
Автор: Mehdi Azizi
Опубликовано , 8 мин
ITMS-90034: твой билд не подписан действующим сертификатом дистрибуции. Проверь подпись через codesign и пересобери store-билд в EAS.
ITMS-90034 появляется, когда ты отправляешь билд в App Store Connect. Ошибка говорит, что твоё приложение или один из его компонентов не подписан сертификатом Apple для отправки (submission certificate), то есть действующим сертификатом дистрибуции. Как исправить: найти, какой бандл подписан неправильно и почему, а потом заново собрать билд, подписанный для App Store.
Этот гайд посвящён только самой ошибке. Если слова «сертификат» и «профиль» для тебя пока туманны, сначала прочитай сертификат разработчика iOS и provisioning profile. Здесь ты найдёшь, как читать сообщение, дерево решений, команды для проверки IPA и исправление с учётными данными, которыми управляет EAS. Для части про EAS я прочитал код EAS CLI 24.10.0, который выбирает сертификат.
Что значит ошибка ITMS-90034?
Вот её классический вид, с примерными именами:
ITMS-90034: Missing or invalid signature. The bundle 'com.example.myapp' at bundle path 'Payload/MyApp.app' is not signed using an Apple submission certificate.
В 2026 году на форуме Apple она встречается и в виде «Validation failed (409) Missing or invalid signature», с тем же текстом и «(ID: 90034)» после него.
«Сертификат для отправки» это сертификат дистрибуции. Справка Apple по сертификатам прямо пишет: сертификаты разработки нужны, чтобы запускать приложение на своих устройствах, а сертификаты дистрибуции нужны, чтобы его распространять или отправлять в App Store Connect.
Смотри на указанный путь: он показывает проблемный бандл. Payload/MyApp.app указывает на само приложение. Путь, который заканчивается на .appex, указывает на расширение, например виджет. Путь на .framework указывает на встроенную библиотеку.
Это не отказ ревьюера. Проверка срабатывает при отправке или во время обработки билда, до TestFlight: этот билд никогда не дойдёт до твоих тестировщиков.
Дерево решений: от сообщения к исправлению
Каждая строка соответствует подсказке, которую ты видишь в сообщении, в командах из следующего раздела или в логах EAS. Иди по порядку: первая подходящая строка и есть твоя зацепка.
| Что ты видишь | Вероятная причина | Исправление |
|---|---|---|
Путь на .appex | Расширение подписано неверно | Объявить расширение |
Signature=adhoc | Билд не подписан | Билд с профилем store |
Apple Development | Билд для разработки | Билд с профилем store |
Найден ProvisionedDevices | Внутренний билд (ad hoc) | Билд с профилем store |
sealed resource | IPA изменили после сборки | Пересобрать билд |
| EAS: «no longer valid» | Сертификат отозван | Новый сертификат |
| Всё валидно | Сбой на стороне Apple | Отправить заново, потом сообщить |
Проверяем IPA четырьмя командами
Скачай IPA со страницы билда на expo.dev и открой терминал на Mac.
1. Кто подписал приложение?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
codesign пишет в поток ошибок, отсюда 2>&1. Согласно технической заметке Apple TN3161, каждая строка Authority это звено цепочки доверия. Первая должна начинаться с Apple Distribution: или iPhone Distribution:, а за ней идёт название твоей команды. Второй вариант относится к старому типу iOS Distribution: судя по коду, EAS CLI 24.10.0 до сих пор создаёт сертификаты этого типа. Если видишь Apple Development:, это билд для разработки. Если видишь Signature=adhoc и ни одной строки Authority, бинарник не подписан ни одним сертификатом.
2. Меняли ли приложение после подписи?
codesign --verify --deep --strict -vv ipa/Payload/*.app
Тебе нужно увидеть valid on disk, а затем satisfies its Designated Requirement. TN3161 уточняет, что гарантирует эта проверка: все ожидаемые файлы на месте, ни один не добавлен, ни один не изменён. На тестовом бандле, который я подписал, а потом поправил, команда ответила a sealed resource is missing or invalid, а затем file modified: с именем изменённого файла. Опция --deep здесь нужна только для проверки, никогда для подписи: на форуме Apple инженер из команды поддержки не советует использовать её при подписи.
3. Какой профиль встроен?
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profile.plist
plutil -extract ProvisionedDevices xml1 -o - profile.plist
plutil -extract ExpirationDate raw profile.plist
Это команды из заметки TN3125 о профилях. Профиль App Store не содержит списка устройств: вторая строка должна ответить Could not extract value. Если она выводит идентификаторы устройств, это профиль ad hoc, то есть внутренний билд. Третья строка показывает дату истечения профиля.
4. Расширения и фреймворки подписаны так же?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
Каждый компонент должен показывать ту же строку Authority, что и приложение. Если какой-то отличается, именно он и указан в сообщении.
Если хочешь проверить до отправки, TN3161 советует altool: это та же проверка, что и кнопка Validate App в Xcode. Нужен API-ключ App Store Connect, файл AuthKey_<KEY_ID>.p8 которого кладётся в ~/.appstoreconnect/private_keys:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
Исправляем через EAS, причина за причиной
В Apple ушёл внутренний билд или билд для разработки
Согласно документации Expo по eas.json, билды с "distribution": "internal" не подписываются для сторов: они используют профиль ad hoc. Билд, который можно отправить, даёт только профиль с дистрибуцией store, это значение по умолчанию. Надёжнее всего отправлять билд, который ты только что собрал, не выбирая его вручную:
eas build --platform ios --profile production --auto-submit
Если используешь eas submit --path, проверь, что файл действительно твой последний store-билд. На форуме Apple одна команда обнаружила, что её инструмент отправки каждый раз отправлял старый IPA, лежавший в git.
Забытое расширение
Каждое расширение это отдельный бандл, со своим идентификатором и своим профилем. В Expo-проекте с генерацией нативного кода страница Expo о расширениях iOS требует объявлять их в extra.eas.build.experimental.ios.appExtensions. Тогда EAS CLI знает о них до сборки и создаёт или проверяет их учётные данные. Большинство библиотек, которые добавляют расширение, сами прописывают это объявление через свой плагин.
Solys, мой будильник с мини-играми, содержит четыре расширения: виджет и три расширения Screen Time. Все четыре объявлены в его конфигурации, и у EAS есть профиль для каждого. Расширение, добавленное вручную в Xcode без такого объявления, это главный подозреваемый, если в сообщении путь на .appex.
Отозванный или истёкший сертификат
Страница Apple о сертификатах говорит однозначно: билд, подписанный истёкшим или отозванным сертификатом, отправить уже нельзя. Билд, который уже загружен, но ещё не отправлен на ревью, может даже получить статус Invalid Binary, если его сертификат отозвали.
Код EAS CLI 24.10.0 показывает, когда эта ситуация остаётся незамеченной:
- Интерактивный билд с входом в Apple: EAS сравнивает свой сертификат с теми, что ещё действуют у Apple. Если его там нет, выводится «Current distribution certificate is no longer valid in Apple Dev Portal» и предлагается выбрать или создать другой.
- Интерактивный билд без входа: EAS проверяет только даты и предупреждает, что пропускает проверку у Apple.
- Неинтерактивный билд в CI: EAS выводит «Distribution Certificate is not validated for non-interactive builds» и всё равно подписывает.
В CI EAS не перепроверяет сам сертификат: отзыв может проявиться только при отправке. Исправление: запусти интерактивный билд со входом в свой аккаунт Apple или зайди в eas credentials --platform ios, меню Build Credentials, затем «Distribution Certificate: Add a new one to your account». Профили со старым сертификатом становятся недействительными: EAS проверит их при следующем билде и пересоздаст. Ограничения Apple на количество сертификатов описаны в гайде по сертификату разработчика iOS.
Бинарник изменили после подписи
Подпись запечатывает код, ресурсы и метаданные хешами, как объясняет заметка Apple TN3126. Если распаковать IPA, поменять файл и запаковать обратно, эта печать ломается. Вноси изменения в конфигурацию и пересобирай билд. Никогда не правь IPA, собранный EAS.
Та же логика для кода, лежащего не там, где надо, например внутри архива .zip: App Store не может его переподписать. Допустимые места Apple описывает на странице о содержимом бандла.
Локальные учётные данные
Если твой профиль EAS использует "credentialsSource": "local", файл credentials.json указывает на сертификат .p12 и профиль .mobileprovision. Проверь профиль командами из шага 3: он должен быть типа App Store и содержать твой текущий сертификат дистрибуции. И держи эти файлы вне репозитория, как и API-ключи Expo-приложения.
Когда всё валидно
Остаётся неприятный случай. На форуме Apple разработчики пишут, что ошибка исчезает, если отправить тот же билд повторно, ничего не меняя. В августе и сентябре 2026 года две ветки описывают обратное: новые сертификат и профиль, подпись проверена, а ошибка не уходит. В одной из них инженер Apple советует отправить баг-репорт с IPA, анализом подписи и логами Transporter, а потом связаться с App Store Connect.
Так что отправь билд ещё раз с новым номером билда. Если ошибка возвращается, хотя все четыре команды чистые, сообщи о ней в Apple с этими материалами. Не отзывай сертификат на автомате: ничего это не решит, а профили станут недействительными.
Как отправить билд без неприятных сюрпризов
Подпись проверяется за две минуты до отправки. Другие автоматические проверки требуют той же аккуратности, например ITMS-90725 про версию Xcode или ITMS-90683 про тексты запросов разрешений. Весь путь от билда до отправки без Mac описан в статье как опубликовать iOS-приложение без Mac.
С отказами ревьюера нужно разбираться вдумчивее: порядок действий на странице приложение отклонено Apple, а самые частые причины в статье почему Apple отклоняет приложение.
Чтобы проверить всё перед отправкой, в Review Kit есть мой чеклист и скиллы для Claude Code, которые просматривают твой проект. Если отправка застряла и нужен живой взгляд, забронируй час со мной: разберём твой проект по видеосвязи, прямо на твоём экране. А если готовишь первый релиз, пройди бесплатную диагностику: она расставит шаги по порядку и пришлёт тебе мой чеклист против отказов Apple.
Частые вопросы
ITMS-90034 это отказ App Review?
Нет. Это автоматическая проверка при отправке билда, до TestFlight и до любого ревью. Твоё приложение никто не открывал: Apple просто увидела, что его подпись сделана не действующим сертификатом дистрибуции.
Нужно ли отзывать сертификат дистрибуции, чтобы исправить ITMS-90034?
Только если он скомпрометирован или уже недействителен. Отзыв рабочего сертификата делает профили недействительными и не устраняет причину. Сначала прочитай подпись IPA через codesign, потом исправь то, на что указывает дерево решений.
Можно ли исправить ITMS-90034 обновлением по воздуху?
Нет. Подпись это часть бинарника, а отклонённый билд никогда не станет пригодным. Нужно собрать новый, правильно подписанный бинарник и отправить его заново.
Почему ошибка указывает на мой виджет, а не на приложение?
Потому что виджет это отдельный бандл, подписанный своим профилем. Если он не объявлен в EAS или подписан иначе, он ломает всю отправку. Объяви расширение в конфигурации и пересобери билд.
Что делать, если codesign говорит, что всё валидно?
Проверь ещё встроенный профиль и каждое расширение. Если всё чисто, отправь ещё раз с новым номером билда. Если ошибка не уходит, отправь в Apple отчёт с IPA, выводом codesign и логами отправки.

