ITMS-90034: popravi »Missing or invalid signature«
Avtor: Mehdi Azizi
Objavljeno , 8 min
ITMS-90034 pomeni, da tvoj build ni podpisan z veljavnim distribucijskim certifikatom. Preveri podpis s codesign in z EAS naredi nov build za store.
ITMS-90034 se pojavi, ko pošlješ build v App Store Connect. Pove, da tvoja aplikacija ali ena od njenih komponent ni podpisana z Applovim certifikatom za oddajo (submission certificate), torej z veljavnim distribucijskim certifikatom. Rešitev: ugotovi, kateri bundle je napačno podpisan in zakaj, nato naredi nov build, podpisan za App Store.
Ta vodič se drži same napake. Če ti besedi certifikat in profil nista čisto jasni, najprej preberi razvijalski certifikat iOS in provisioning profile. Tukaj najdeš sporočilo, ki ga moraš prebrati, odločitveno drevo, ukaze za pregled IPA in popravek z identifikatorji, ki jih upravlja EAS. Za del o EAS sem prebral kodo EAS CLI 24.10.0, ki izbere certifikat.
Kaj pomeni napaka ITMS-90034?
Tako je videti njena klasična oblika, s primeri imen:
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.
Leta 2026 se na Applovem forumu pojavlja tudi v obliki »Validation failed (409) Missing or invalid signature«, ki ji sledi isto besedilo in »(ID: 90034)«.
»Certifikat za oddajo« je distribucijski certifikat. Applova pomoč o certifikatih to jasno piše: razvijalski certifikati so za zagon aplikacije na tvojih napravah, distribucijski pa za distribucijo ali pošiljanje v App Store Connect.
Preberi navedeno pot: kaže na problematični bundle. Payload/MyApp.app pomeni samo aplikacijo. Pot, ki se konča z .appex, pomeni razširitev, na primer widget. Pot s .framework pomeni vgrajeno knjižnico.
To ni zavrnitev reviewerja. Preverjanje pade ob pošiljanju ali med obdelavo builda, pred TestFlightom: ta build ne bo nikoli prišel do tvojih testerjev.
Odločitveno drevo: od sporočila do popravka
Vsaka vrstica ustreza namigu, ki ga prebereš v sporočilu, v ukazih iz naslednjega razdelka ali v dnevnikih EAS. Pojdi po vrsti: prva, ki se ujema, ti pokaže smer.
| Kaj opaziš | Verjeten vzrok | Popravek |
|---|---|---|
Pot s .appex | Napačno podpisana razširitev | Prijavi razširitev |
Signature=adhoc | Nepodpisan build | Build s profilom store |
Apple Development | Razvojni build | Build s profilom store |
Prebran ProvisionedDevices | Interni build (ad hoc) | Build s profilom store |
sealed resource | IPA spremenjena naknadno | Ponovi build |
| EAS: »no longer valid« | Preklican certifikat | Nov certifikat |
| Vse je veljavno | Težava na Applovi strani | Pošlji znova, nato prijavi |
Pregled IPA v štirih ukazih
Prenesi IPA s strani builda na expo.dev, nato odpri terminal na Macu.
1. Kdo je podpisal aplikacijo?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
codesign piše na izhod za napake, zato 2>&1. Po Applovi tehnični opombi TN3161 je vsaka vrstica Authority člen verige zaupanja. Prva se mora začeti z Apple Distribution: ali iPhone Distribution:, ki mu sledi ime tvoje ekipe. Druga oznaka pripada staremu tipu iOS Distribution: glede na kodo EAS CLI 24.10.0 še vedno ustvarja certifikate tega tipa. Če prebereš Apple Development:, gre za razvojni build. Če prebereš Signature=adhoc brez vrstice Authority, binarne datoteke ni podpisal noben certifikat.
2. Ali je bila aplikacija spremenjena po podpisu?
codesign --verify --deep --strict -vv ipa/Payload/*.app
Želiš prebrati valid on disk, nato satisfies its Designated Requirement. TN3161 natančno pove, kaj to preverjanje zagotavlja: vse pričakovane datoteke so na mestu, nobena ni bila dodana in nobena spremenjena. Na testnem bundlu, ki sem ga podpisal in nato popravil, ukaz odgovori a sealed resource is missing or invalid, nato file modified: in spremenjeno datoteko. Možnost --deep je tu za preverjanje, nikoli za podpisovanje: na Applovem forumu jo inženir iz podporne ekipe odsvetuje za podpisovanje.
3. Kateri profil je vgrajen?
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profil.plist
plutil -extract ProvisionedDevices xml1 -o - profil.plist
plutil -extract ExpirationDate raw profil.plist
To so ukazi iz opombe TN3125 o profilih. Profil App Store ne vsebuje seznama naprav: druga vrstica mora odgovoriti Could not extract value. Če izpiše identifikatorje naprav, gre za profil ad hoc, profil internega builda. Tretja vrne datum poteka profila.
4. Ali so razširitve in frameworki podpisani enako?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
Vsaka komponenta mora izpisati isto vrstico Authority kot aplikacija. Če kakšna odstopa, je prav ona tista, ki jo navaja sporočilo.
Če želiš preveriti pred pošiljanjem, TN3161 priporoča altool, isto preverjanje kot gumb Validate App v Xcodu. Potrebuješ API ključ App Store Connect, katerega datoteka AuthKey_<KEY_ID>.p8 gre v ~/.appstoreconnect/private_keys:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
Popravek z EAS, vzrok za vzrokom
Interni ali razvojni build, poslan Applu
Po Expovi dokumentaciji o eas.json buildi z "distribution": "internal" niso podpisani za trgovine: uporabljajo profil ad hoc. Build, ki ga lahko pošlješ, ustvari samo profil z distribucijo store, ki je privzeta vrednost. Najvarneje je poslati build, ki si ga pravkar zgradil, brez ročnega izbiranja:
eas build --platform ios --profile production --auto-submit
Če uporabljaš eas submit --path, preveri, da je datoteka res tvoj zadnji store build. Na Applovem forumu je neka ekipa ugotovila, da je njihovo orodje za pošiljanje vsakič poslalo star IPA, shranjen v gitu.
Pozabljena razširitev
Vsaka razširitev je ločen bundle, s svojim identifikatorjem in lastnim profilom. V projektu Expo z generiranjem native kode Expova stran o iOS razširitvah zahteva, da jih prijaviš v extra.eas.build.experimental.ios.appExtensions. EAS CLI jih tako pozna pred buildom in ustvari ali preveri njihove identifikatorje. Večina knjižnic, ki dodajo razširitev, to prijavo napiše namesto tebe prek svojega plugina.
Solys, moja budilka z mini igrami, vsebuje štiri razširitve: widget in tri razširitve za Screen Time. Vse štiri so prijavljene v njeni konfiguraciji in EAS ima profil za vsako. Razširitev, ročno dodana v Xcodu brez te prijave, je idealen kandidat za pot s .appex v sporočilu.
Preklican ali potekel certifikat
Applova stran o certifikatih je jasna: builda, podpisanega s poteklim ali preklicanim certifikatom, ne moreš več poslati. Build, ki je že poslan, a še ni oddan, lahko celo preide v stanje Invalid Binary, če je bil njegov certifikat preklican.
Koda EAS CLI 24.10.0 pokaže, kdaj ta primer ostane neopažen:
- Interaktiven build, povezan z Applom: EAS primerja svoj certifikat s tistimi, ki so pri Applu še veljavni. Če ga tam ni več, izpiše »Current distribution certificate is no longer valid in Apple Dev Portal« in ti ponudi, da izbereš ali ustvariš novega.
- Interaktiven build, brez povezave: EAS preveri samo datume in opozori, da preskoči preverjanje pri Applu.
- Neinteraktiven build, v CI: EAS izpiše »Distribution Certificate is not validated for non-interactive builds« in vseeno podpiše.
V CI EAS samega certifikata ne preveri ponovno: preklic se lahko pokaže šele ob pošiljanju. Popravek: zaženi interaktiven build, povezan s tvojim Applovim računom, ali uporabi eas credentials --platform ios, meni Build Credentials, nato »Distribution Certificate: Add a new one to your account«. Profili, ki so vsebovali stari certifikat, postanejo neveljavni: EAS jih ob naslednjem buildu preveri in ustvari znova. Applove omejitve števila certifikatov so podrobno opisane v vodiču o razvijalskem certifikatu iOS.
Binarna datoteka, spremenjena po podpisu
Podpis zapečati kodo, vire in metapodatke z zgoščenimi vrednostmi, kot pojasnjuje Applova opomba TN3126. Če IPA razpakiraš, da spremeniš datoteko, in jo nato znova stisneš, ta pečat zlomiš. Spremembo naredi v konfiguraciji, nato ponovi build. Nikoli ne popravljaj IPA, ki jo ustvari EAS.
Enaka logika velja za kodo na napačnem mestu, na primer v arhivu .zip: App Store je ne more ponovno podpisati. Apple dovoljena mesta opisuje na strani o vsebini bundla.
Lokalni identifikatorji
Če tvoj EAS profil uporablja "credentialsSource": "local", tvoja datoteka credentials.json kaže na certifikat .p12 in profil .mobileprovision. Profil preveri z ukazi iz 3. koraka: biti mora tipa App Store in vsebovati tvoj trenutni distribucijski certifikat. Te datoteke pa hrani zunaj repozitorija, tako kot API ključe aplikacije Expo.
Ko je vse veljavno
Ostane še en frustrirajoč primer. Na Applovem forumu razvijalci vidijo, da napaka izgine, ko isti build pošljejo znova, ne da bi karkoli spremenili. Avgusta in septembra 2026 dve niti opisujeta ravno nasprotno: nov certifikat in profil, preverjen podpis, a napaka ostaja. V eni od njiju Applov inženir svetuje prijavo hrošča z IPA, analizo podpisa in dnevniki Transporterja, nato pa stik z App Store Connect.
Torej pošlji enkrat znova z novo številko builda. Če se napaka vrne, čeprav so vsi štirje ukazi čisti, jo prijavi Applu s temi podatki. Ne prekliči certifikata po refleksu: s tem ne rešiš ničesar več, profile pa narediš neveljavne.
Pošlji build brez neprijetnih presenečenj
Podpis preveriš v dveh minutah pred pošiljanjem. Druga samodejna preverjanja zahtevajo enako natančnost, na primer ITMS-90725 za različico Xcoda ali ITMS-90683 za besedila dovoljenj. Celotna pot od builda do pošiljanja, brez Maca, je opisana v objavi iOS aplikacije brez Maca.
Zavrnitve reviewerja zahtevajo več razmisleka: postopek je na strani aplikacija, ki jo je Apple zavrnil, najpogostejši razlogi pa v članku zakaj Apple zavrne aplikacijo.
Če želiš pregledati svojo prijavo pred pošiljanjem, Review Kit združuje moj kontrolni seznam in skille za Claude Code, ki pregledajo tvoj projekt. Če se ti pošiljanje zatakne in želiš človeški pogled, rezerviraj uro z mano: tvoj projekt pregledava na videoklicu, na tvojem zaslonu. Če pa pripravljaš svojo prvo objavo, naredi brezplačno diagnostiko: koraki se uredijo po vrsti in dobiš moj kontrolni seznam proti Applovim zavrnitvam.
Pogosta vprašanja
Ali je ITMS-90034 zavrnitev App Review?
Ne. Gre za samodejno preverjanje ob pošiljanju builda, pred TestFlightom in pred kakršnimkoli pregledom. Nihče ni odprl tvoje aplikacije: Apple je le ugotovil, da njen podpis ne prihaja iz veljavnega distribucijskega certifikata.
Ali moram preklicati distribucijski certifikat, da popravim ITMS-90034?
Samo če je ogrožen ali že neveljaven. Preklic delujočega certifikata naredi tvoje profile neveljavne, vzroka pa ne odpravi. Najprej preberi podpis svoje IPA s codesign, nato popravi tisto, kar pokaže odločitveno drevo.
Ali lahko ITMS-90034 popravim s posodobitvijo na daljavo?
Ne. Podpis je del binarne datoteke, zavrnjeni build pa ne bo nikoli uporaben. Ustvariti moraš novo, pravilno podpisano binarno datoteko in jo poslati znova.
Zakaj napaka navaja moj widget in ne aplikacije?
Ker je widget ločen bundle, podpisan s svojim profilom. Če ni prijavljen v EAS ali je bil podpisan drugače, zaradi njega pade celotno pošiljanje. Prijavi razširitev v konfiguraciji in ponovi build.
Kaj naj naredim, če codesign pravi, da je vse veljavno?
Preveri tudi vgrajeni profil in vsako razširitev. Če je vse čisto, pošlji enkrat znova z novo številko builda. Če napaka ostane, pošlji Applu prijavo z IPA, izpisom codesign in dnevniki pošiljanja.

