# ITMS-90034: popravi »Missing or invalid signature«

> ITMS-90034 pomeni, da tvoj build ni podpisan z veljavnim distribucijskim certifikatom. Preveri podpis s codesign in z EAS naredi nov build za store.

Izvirna stran: [ITMS-90034: popravi »Missing or invalid signature«](https://devoria.fr/sl/blog/itms-90034-missing-invalid-signature)
Avtor: [Mehdi Azizi](https://devoria.fr/sl/mehdi-azizi)
Objava: 2026-11-04
Zadnja revizija vsebine: 2026-11-04


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](https://devoria.fr/sl/blog/certifikat-razvijalca-ios-provisioning-profile-expo). 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](https://developer.apple.com/help/account/certificates/certificates-overview) 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?**

```bash
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](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates) 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?**

```bash
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?**

```bash
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](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles). 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?**

```bash
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`:

```bash
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](https://docs.expo.dev/build/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**:

```bash
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](https://docs.expo.dev/build-reference/app-extensions/) 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](https://developer.apple.com/support/certificates/) 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](https://devoria.fr/sl/blog/certifikat-razvijalca-ios-provisioning-profile-expo).

### Binarna datoteka, spremenjena po podpisu

Podpis zapečati kodo, vire in metapodatke z zgoščenimi vrednostmi, kot pojasnjuje [Applova opomba TN3126](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes). Č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](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle).

### 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](https://devoria.fr/sl/blog/skrivni-api-kljuc-aplikacija-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](https://devoria.fr/sl/blog/itms-90725-sdk-version-issue-expo) za različico Xcoda ali [ITMS-90683](https://devoria.fr/sl/blog/itms-90683-missing-purpose-string-expo) za besedila dovoljenj. Celotna pot od builda do pošiljanja, brez Maca, je opisana v [objavi iOS aplikacije brez Maca](https://devoria.fr/sl/blog/objava-ios-aplikacije-brez-maca-expo-eas).

Zavrnitve reviewerja zahtevajo več razmisleka: postopek je na strani [aplikacija, ki jo je Apple zavrnil](https://devoria.fr/sl/expertise/apple-zavrnil-aplikacijo), najpogostejši razlogi pa v članku [zakaj Apple zavrne aplikacijo](https://devoria.fr/sl/blog/apple-zavrnil-aplikacijo-razlogi).

Če želiš pregledati svojo prijavo pred pošiljanjem, [Review Kit](https://devoria.fr/sl/kits/app-review) 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](https://devoria.fr/sl/coaching): tvoj projekt pregledava na videoklicu, na tvojem zaslonu. Če pa pripravljaš svojo prvo objavo, [naredi brezplačno diagnostiko](https://devoria.fr/sl/diagnostic): 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.


## Tvoj projekt

[Review Kit](https://devoria.fr/sl/kits/app-review): Moj kontrolni seznam za pregled v App Store, moje popravljene zavrnitve Applea, seznam za Google Play in trije skilli za Claude Code. 49 €.

[iOS & Android Kit](https://devoria.fr/sl/kits/ios): Ustvari svojo aplikacijo za iPhone in Android s Claude Code: začetna koda mojih aplikacij, pot do trgovin in vsi kompleti. 99 €.

[Diagnoza: kaj te loči od tvoje aplikacije za iPhone](https://devoria.fr/sl/diagnostic): 7 vprašanj, 60 sekund: izveš, kaj te zares ovira pri objavi aplikacije za iPhone, dobiš pot v 4 korakih in komplet, ki ti ustreza.
