ITMS-90034: jak naprawić „Missing or invalid signature”
Autor: Mehdi Azizi
Opublikowano , 8 min
ITMS-90034: twój build nie jest podpisany ważnym certyfikatem dystrybucyjnym. Sprawdź podpis przez codesign i zrób nowy build store w EAS.
ITMS-90034 pojawia się, kiedy wysyłasz build do App Store Connect. Oznacza, że twoja aplikacja albo jeden z jej komponentów nie jest podpisany certyfikatem Apple do wysyłki (submission certificate), czyli ważnym certyfikatem dystrybucyjnym. Rozwiązanie: znajdź, który bundle jest źle podpisany i dlaczego, a potem zrób nowy build podpisany pod App Store.
Ten poradnik skupia się tylko na tym błędzie. Jeśli pojęcia certyfikat i profil są dla ciebie mgliste, przeczytaj najpierw certyfikat dewelopera iOS i provisioning profile. Tutaj znajdziesz komunikat do przeczytania, drzewo decyzyjne, komendy do sprawdzenia IPA i poprawkę z danymi uwierzytelniającymi zarządzanymi przez EAS. Do części o EAS przeczytałem kod EAS CLI 24.10.0, który wybiera certyfikat.
Co oznacza błąd ITMS-90034?
Oto jego klasyczna postać, z przykładowymi nazwami:
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.
W 2026 roku na forum Apple pojawia się też w formie „Validation failed (409) Missing or invalid signature”, z tym samym tekstem i dopiskiem „(ID: 90034)”.
„Submission certificate” to certyfikat dystrybucyjny. Pomoc Apple o certyfikatach mówi to wprost: certyfikaty deweloperskie służą do uruchamiania aplikacji na twoich urządzeniach, a dystrybucyjne do jej dystrybucji lub wysyłki do App Store Connect.
Przeczytaj podaną ścieżkę: wskazuje winny bundle. Payload/MyApp.app to sama aplikacja. Ścieżka kończąca się na .appex to rozszerzenie, na przykład widget. Ścieżka z .framework to osadzona biblioteka.
To nie jest odrzucenie przez reviewera. Walidacja pada przy wysyłce albo podczas przetwarzania buildu, przed TestFlight: ten build nigdy nie trafi do twoich testerów.
Drzewo decyzyjne: od komunikatu do poprawki
Każdy wiersz to wskazówka, którą odczytasz z komunikatu, z komend z następnej sekcji albo z logów EAS. Sprawdzaj po kolei: pierwszy pasujący wiersz wskazuje trop.
| Co widzisz | Prawdopodobna przyczyna | Poprawka |
|---|---|---|
Ścieżka z .appex | Źle podpisane rozszerzenie | Zadeklaruj rozszerzenie |
Signature=adhoc | Niepodpisany build | Build z profilem store |
Apple Development | Build deweloperski | Build z profilem store |
Odczytane ProvisionedDevices | Build wewnętrzny (ad hoc) | Build z profilem store |
sealed resource | IPA zmodyfikowana później | Zrób build od nowa |
| EAS: „no longer valid” | Unieważniony certyfikat | Nowy certyfikat |
| Wszystko jest ważne | Problem po stronie Apple | Wyślij ponownie, potem zgłoś |
Sprawdź swoją IPA w czterech komendach
Pobierz IPA ze strony buildu na expo.dev, potem otwórz terminal na swoim Macu.
1. Kto podpisał aplikację?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
codesign pisze na wyjście błędów, stąd 2>&1. Według noty technicznej Apple TN3161 każda linia Authority to ogniwo łańcucha zaufania. Pierwsza musi zaczynać się od Apple Distribution: albo iPhone Distribution:, a po niej nazwa twojego zespołu. Druga etykieta to stary typ iOS Distribution: według kodu EAS CLI 24.10.0 wciąż tworzy certyfikaty tego typu. Jeśli widzisz Apple Development:, to build deweloperski. Jeśli widzisz Signature=adhoc bez żadnej linii Authority, binarka nie jest podpisana żadnym certyfikatem.
2. Czy aplikację zmieniono po podpisaniu?
codesign --verify --deep --strict -vv ipa/Payload/*.app
Chcesz zobaczyć valid on disk, a potem satisfies its Designated Requirement. TN3161 wyjaśnia, co gwarantuje ta kontrola: wszystkie oczekiwane pliki są na miejscu, żadnego nie dodano, żadnego nie zmieniono. Na testowym bundle, który podpisałem, a potem zmodyfikowałem, komenda zwraca a sealed resource is missing or invalid, a potem file modified: i zmieniony plik. Opcja --deep służy tu do weryfikacji, nigdy do podpisywania: na forum Apple inżynier z zespołu wsparcia odradza jej użycie przy podpisywaniu.
3. Jaki profil jest osadzony?
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
To komendy z noty TN3125 o profilach. Profil App Store nie zawiera listy urządzeń: druga linia powinna zwrócić Could not extract value. Jeśli wyświetla identyfikatory urządzeń, to profil ad hoc, czyli build wewnętrzny. Trzecia podaje datę wygaśnięcia profilu.
4. Czy rozszerzenia i frameworki są podpisane tak samo?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
Każdy komponent powinien pokazać tę samą linię Authority co aplikacja. Jeśli któryś się różni, to właśnie on jest podany w komunikacie.
Jeśli chcesz sprawdzić wszystko przed wysyłką, TN3161 poleca altool, tę samą kontrolę co przycisk Validate App w Xcode. Wymaga klucza API App Store Connect, którego plik AuthKey_<KEY_ID>.p8 trzymasz w ~/.appstoreconnect/private_keys:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
Poprawka w EAS, przyczyna po przyczynie
Build wewnętrzny lub deweloperski wysłany do Apple
Według dokumentacji Expo o eas.json buildy z "distribution": "internal" nie są podpisane pod sklepy: używają profilu ad hoc. Tylko profil z dystrybucją store, czyli wartością domyślną, daje build, który da się wysłać. Najbezpieczniej wysłać build, który właśnie zbudowałeś, bez wybierania go ręcznie:
eas build --platform ios --profile production --auto-submit
Jeśli używasz eas submit --path, sprawdź, czy plik to na pewno twój ostatni build store. Na forum Apple pewien zespół odkrył, że ich narzędzie do wysyłki za każdym razem wysyłało stary IPA, trzymany w gicie.
Zapomniane rozszerzenie
Każde rozszerzenie to osobny bundle, z własnym identyfikatorem i własnym profilem. W projekcie Expo z generowaniem kodu natywnego strona Expo o rozszerzeniach iOS każe deklarować je w extra.eas.build.experimental.ios.appExtensions. Wtedy EAS CLI zna je przed buildem i tworzy lub weryfikuje ich dane uwierzytelniające. Większość bibliotek, które dodają rozszerzenie, zapisuje tę deklarację za ciebie, przez swój plugin.
Solys, mój budzik z minigrami, zawiera cztery rozszerzenia: widget i trzy rozszerzenia Screen Time. Wszystkie cztery są zadeklarowane w jego konfiguracji, a EAS ma profil dla każdego. Rozszerzenie dodane ręcznie w Xcode, bez tej deklaracji, to idealny kandydat na ścieżkę z .appex w komunikacie.
Unieważniony lub wygasły certyfikat
Strona Apple o certyfikatach mówi jasno: nie możesz już wysłać buildu podpisanego wygasłym lub unieważnionym certyfikatem. Build już wysłany, ale jeszcze nie zgłoszony do recenzji, może nawet przejść w status Invalid Binary, jeśli jego certyfikat został unieważniony.
Kod EAS CLI 24.10.0 pokazuje, kiedy ten przypadek przechodzi niezauważony:
- Build interaktywny, z połączeniem z Apple: EAS porównuje swój certyfikat z tymi, które wciąż są ważne w Apple. Jeśli go tam nie ma, wyświetla „Current distribution certificate is no longer valid in Apple Dev Portal” i proponuje wybranie lub utworzenie nowego.
- Build interaktywny, bez połączenia: EAS sprawdza tylko daty i ostrzega, że pomija weryfikację w Apple.
- Build nieinteraktywny, w CI: EAS wyświetla „Distribution Certificate is not validated for non-interactive builds” i mimo to podpisuje.
W CI EAS nie weryfikuje ponownie samego certyfikatu: unieważnienie może wyjść na jaw dopiero przy wysyłce. Poprawka: uruchom build interaktywny połączony z twoim kontem Apple albo użyj eas credentials --platform ios, menu Build Credentials, potem „Distribution Certificate: Add a new one to your account”. Profile zawierające stary certyfikat stają się nieważne: EAS sprawdzi je przy następnym buildzie i utworzy na nowo. Limity Apple dotyczące liczby certyfikatów opisuję w poradniku o certyfikacie dewelopera iOS.
Binarka zmieniona po podpisaniu
Podpis pieczętuje kod, zasoby i metadane za pomocą skrótów (hashy), jak wyjaśnia nota Apple TN3126. Rozpakowanie IPA, zmiana pliku i ponowne spakowanie łamie tę pieczęć. Wprowadź zmianę w konfiguracji, a potem zrób nowy build. Nigdy nie modyfikuj IPA wygenerowanej przez EAS.
Ta sama logika dotyczy kodu umieszczonego w złym miejscu, na przykład w archiwum .zip: App Store nie może go ponownie podpisać. Apple opisuje dozwolone lokalizacje na stronie o zawartości bundle.
Lokalne dane uwierzytelniające
Jeśli twój profil EAS używa "credentialsSource": "local", plik credentials.json wskazuje na certyfikat .p12 i profil .mobileprovision. Sprawdź profil komendami z kroku 3: musi być typu App Store i zawierać twój aktualny certyfikat dystrybucyjny. I trzymaj te pliki poza repozytorium, tak jak klucze API aplikacji Expo.
Kiedy wszystko jest ważne
Zostaje jeden frustrujący przypadek. Na forum Apple deweloperzy widzą, jak błąd znika po ponownym wysłaniu tego samego buildu, bez żadnych zmian. W sierpniu i wrześniu 2026 dwa wątki opisują odwrotną sytuację: nowy certyfikat i profil, zweryfikowany podpis, a błąd nie znika. W jednym z nich inżynier Apple radzi zgłosić błąd z IPA, analizą podpisu i logami z Transportera, a potem skontaktować się z App Store Connect.
Wyślij więc ponownie raz, z nowym numerem buildu. Jeśli błąd wraca, a twoje cztery komendy nie pokazują problemów, zgłoś go do Apple z tymi materiałami. Nie unieważniaj certyfikatu odruchowo: niczego więcej to nie naprawi, a unieważni twoje profile.
Wyślij build bez przykrych niespodzianek
Podpis sprawdzisz w dwie minuty przed wysyłką. Inne automatyczne kontrole wymagają takiej samej skrupulatności, na przykład ITMS-90725 dla wersji Xcode albo ITMS-90683 dla opisów uprawnień. Cała ścieżka od buildu do wysyłki, bez Maca, jest w publikacja aplikacji iOS bez Maca.
Odrzucenia przez reviewera wymagają więcej dystansu: jak do nich podejść, opisuję na stronie aplikacja odrzucona przez Apple, a najczęstsze powody w dlaczego Apple odrzuca aplikację.
Żeby sprawdzić wszystko przed wysyłką, Review Kit zawiera moją checklistę i skille Claude Code, które przeglądają twój projekt. Jeśli wysyłka się blokuje i chcesz, żeby spojrzał na to człowiek, zarezerwuj ze mną godzinę: przejdziemy przez twój projekt na wideorozmowie, na twoim ekranie. A jeśli przygotowujesz swoje pierwsze wydanie, zrób darmową diagnozę: ułoży kroki we właściwej kolejności i wyśle ci moją checklistę przeciw odrzuceniom Apple.
Najczęściej zadawane pytania
Czy ITMS-90034 to odrzucenie przez App Review?
Nie. To automatyczna walidacja przy wysyłce buildu, przed TestFlight i przed jakąkolwiek recenzją. Nikt nie otworzył twojej aplikacji: Apple tylko stwierdził, że jej podpis nie pochodzi z ważnego certyfikatu dystrybucyjnego.
Czy muszę unieważnić certyfikat dystrybucyjny, żeby naprawić ITMS-90034?
Tylko jeśli został skompromitowany albo już jest nieważny. Unieważnienie działającego certyfikatu unieważnia twoje profile, a przyczyny nie usuwa. Zacznij od sprawdzenia podpisu IPA przez codesign, potem popraw to, co wskaże drzewo decyzyjne.
Czy da się naprawić ITMS-90034 aktualizacją zdalną?
Nie. Podpis jest częścią binarki, a odrzucony build nigdy nie będzie użyteczny. Musisz zrobić nową, poprawnie podpisaną binarkę i wysłać ją ponownie.
Dlaczego błąd wskazuje mój widget, a nie aplikację?
Bo widget to osobny bundle, podpisany własnym profilem. Jeśli nie jest zadeklarowany w EAS albo został podpisany inaczej, cała wysyłka się nie powiedzie. Zadeklaruj rozszerzenie w konfiguracji i zrób nowy build.
Co zrobić, jeśli codesign mówi, że wszystko jest ważne?
Sprawdź też osadzony profil i każde rozszerzenie. Jeśli wszystko jest w porządku, wyślij ponownie raz, z nowym numerem buildu. Jeśli błąd się utrzymuje, wyślij zgłoszenie do Apple z IPA, wynikiem codesign i logami wysyłki.

