ITMS-90034: corregir «Missing or invalid signature»
Per Mehdi Azizi
Publicat el , 8 min
ITMS-90034: el teu build no està signat amb un certificat de distribució vàlid. Llegeix-ne la signatura amb codesign i torna a fer un build store amb EAS.
ITMS-90034 apareix quan envies el build a App Store Connect. Diu que la teva app, o algun dels seus components, no està signada amb un certificat de submissió d'Apple, és a dir, un certificat de distribució vàlid. La solució: trobar quin bundle està mal signat i per què, i després tornar a fer un build signat per a l'App Store.
Aquesta guia se centra en l'error. Si les paraules certificat i perfil no et queden clares, llegeix primer certificat de desenvolupador iOS i provisioning profile. Aquí hi trobaràs el missatge que has de llegir, un arbre de decisió, les ordres que inspeccionen la teva IPA i la correcció amb les credencials gestionades per EAS. Per a la part d'EAS, he llegit el codi d'EAS CLI 24.10.0 que tria el certificat.
Què vol dir l'error ITMS-90034?
Aquesta és la seva forma clàssica, amb noms d'exemple:
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.
El 2026, al fòrum d'Apple, també apareix com a «Validation failed (409) Missing or invalid signature», seguit del mateix text i de «(ID: 90034)».
El «certificat de submissió» és el certificat de distribució. L'ajuda d'Apple sobre els certificats ho diu: els certificats de desenvolupament serveixen per executar l'app als teus dispositius, i els de distribució per distribuir-la o enviar-la a App Store Connect.
Llegeix el camí citat: assenyala el bundle culpable. Payload/MyApp.app apunta a l'app mateixa. Un camí que acaba en .appex apunta a una extensió, com un widget. Un camí en .framework apunta a una biblioteca inclosa.
No és el rebuig d'un revisor. La validació salta en l'enviament o durant el processament del build, abans de TestFlight: aquest build no arribarà mai als teus testers.
L'arbre de decisió: del missatge a la correcció
Cada fila correspon a una pista que llegeixes al missatge, a les ordres de la secció següent o als registres d'EAS. Repassa-les en ordre: la primera que coincideixi et dona la pista.
| El que observes | Causa probable | Correcció |
|---|---|---|
Camí en .appex | Extensió mal signada | Declarar l'extensió |
Signature=adhoc | Build no signat | Build amb perfil store |
Apple Development | Build de desenvolupament | Build amb perfil store |
ProvisionedDevices llegit | Build intern (ad hoc) | Build amb perfil store |
sealed resource | IPA modificada després | Refer el build |
| EAS: «no longer valid» | Certificat revocat | Certificat nou |
| Tot és vàlid | Incidència per part d'Apple | Reenviar i després avisar |
Inspeccionar la IPA en quatre ordres
Descarrega la IPA des de la pàgina del build a expo.dev i obre un terminal al Mac.
1. Qui ha signat l'app?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
codesign escriu a la sortida d'error, d'aquí el 2>&1. Segons la nota tècnica TN3161 d'Apple, cada línia Authority és una baula de la cadena de confiança. La primera ha de començar per Apple Distribution: o iPhone Distribution:, seguida del nom del teu equip. La segona etiqueta és la de l'antic tipus iOS Distribution: segons el seu codi, EAS CLI 24.10.0 encara crea certificats d'aquest tipus. Si hi llegeixes Apple Development:, és un build de desenvolupament. Si hi llegeixes Signature=adhoc sense cap línia Authority, el binari no està signat per cap certificat.
2. S'ha modificat l'app després de signar-la?
codesign --verify --deep --strict -vv ipa/Payload/*.app
Vols llegir valid on disk i després satisfies its Designated Requirement. TN3161 precisa què garanteix aquest control: hi són tots els fitxers esperats, no se n'ha afegit cap i no se n'ha modificat cap. En un bundle de prova que vaig signar i després retocar, l'ordre respon a sealed resource is missing or invalid i després file modified: seguit del fitxer canviat. L'opció --deep aquí serveix per verificar, mai per signar: al fòrum d'Apple, un enginyer de l'equip de suport la desaconsella per signar.
3. Quin perfil hi ha inclòs?
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
Són les ordres de la nota TN3125 sobre els perfils. Un perfil App Store no conté cap llista de dispositius: la segona línia ha de respondre Could not extract value. Si mostra identificadors de dispositius, és un perfil ad hoc, el d'un build intern. La tercera dona la data de caducitat del perfil.
4. Les extensions i els frameworks estan signats igual?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
Cada component ha de mostrar la mateixa línia Authority que l'app. Si algun se n'aparta, és aquest el que cita el missatge.
Si vols verificar-ho abans de l'enviament, TN3161 recomana altool, el mateix control que el botó Validate App de Xcode. Demana una clau API d'App Store Connect, el fitxer AuthKey_<KEY_ID>.p8 de la qual es guarda a ~/.appstoreconnect/private_keys:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
Corregir amb EAS, causa per causa
Un build intern o de desenvolupament enviat a Apple
Segons la documentació d'Expo sobre eas.json, els builds amb "distribution": "internal" no estan signats per a les botigues: fan servir un perfil ad hoc. Només un perfil amb distribució store, el valor per defecte, produeix un build que es pot enviar. El més segur és enviar el build que acabes de construir, sense triar-lo a mà:
eas build --platform ios --profile production --auto-submit
Si fas servir eas submit --path, comprova que el fitxer és de debò el teu últim build store. Al fòrum d'Apple, un equip va descobrir que la seva eina d'enviament reenviava cada vegada una IPA antiga, versionada a git.
Una extensió oblidada
Cada extensió és un bundle a part, amb el seu identificador i el seu propi perfil. En un projecte Expo amb generació nativa, la pàgina d'Expo sobre les extensions iOS demana declarar-les a extra.eas.build.experimental.ios.appExtensions. Així EAS CLI les coneix abans del build i en crea o valida les credencials. La majoria de biblioteques que afegeixen una extensió escriuen aquesta declaració per tu, a través del seu plugin.
Solys, el meu despertador amb minijocs, inclou quatre extensions: un widget i tres extensions de Screen Time. Totes quatre estan declarades a la seva configuració, i EAS té un perfil per a cadascuna. Una extensió afegida a mà a Xcode, sense aquesta declaració, és la candidata ideal per a un camí en .appex al missatge.
Un certificat revocat o caducat
La pàgina d'Apple sobre els certificats és clara: ja no pots enviar un build signat amb un certificat caducat o revocat. Un build ja enviat però encara no sotmès fins i tot pot passar a Invalid Binary si se n'ha revocat el certificat.
El codi d'EAS CLI 24.10.0 mostra quan aquest cas passa desapercebut:
- Build interactiu, connectat a Apple: EAS compara el seu certificat amb els que encara són vàlids a Apple. Si ja no hi és, mostra «Current distribution certificate is no longer valid in Apple Dev Portal» i et proposa triar-ne o crear-ne un.
- Build interactiu, sense connexió: EAS només comprova les dates i avisa que se salta la validació a Apple.
- Build no interactiu, en integració contínua: EAS mostra «Distribution Certificate is not validated for non-interactive builds» i signa igualment.
En integració contínua, EAS no torna a verificar el certificat en si: una revocació pot no veure's fins a l'enviament. La solució: llança un build interactiu connectat al teu compte d'Apple, o fes servir eas credentials --platform ios, menú Build Credentials, i després «Distribution Certificate: Add a new one to your account». Els perfils que contenien l'antic certificat deixen de ser vàlids: EAS els comprova al build següent i els refà. Els límits d'Apple sobre el nombre de certificats es detallen a la guia sobre el certificat de desenvolupador iOS.
Un binari modificat després de la signatura
La signatura segella el codi, els recursos i les metadades amb empremtes, com explica la nota TN3126 d'Apple. Descomprimir la IPA per canviar un fitxer i tornar-la a comprimir trenca aquest segell. Fes el canvi a la configuració i torna a fer un build. No retoquis mai la IPA que genera EAS.
La mateixa lògica val per al codi guardat on no toca, per exemple dins d'un arxiu .zip: l'App Store no el pot tornar a signar. Apple descriu els llocs permesos a la seva pàgina sobre el contingut d'un bundle.
Credencials locals
Si el teu perfil d'EAS fa servir "credentialsSource": "local", el fitxer credentials.json apunta a un certificat .p12 i a un perfil .mobileprovision. Comprova el perfil amb les ordres del pas 3: ha de ser de tipus App Store i contenir el teu certificat de distribució actual. I guarda aquests fitxers fora del repositori, com les claus API d'una app Expo.
Quan tot és vàlid
Queda un cas frustrant. Al fòrum d'Apple, hi ha desenvolupadors que veuen desaparèixer l'error reenviant el mateix build, sense canviar res. A l'agost i al setembre del 2026, dos fils descriuen el contrari: certificat i perfil nous, signatura verificada i l'error que persisteix. En un d'ells, un enginyer d'Apple recomana un informe d'error amb la IPA, l'anàlisi de la signatura i els registres de Transporter, i després contactar amb App Store Connect.
Així doncs, reenvia una vegada amb un número de build nou. Si l'error torna mentre les teves quatre ordres surten netes, comunica-ho a Apple amb aquests elements. No revoquis el certificat per reflex: no soluciona res més i invalida els teus perfils.
Enviar el build sense sorpreses
Una signatura es verifica en dos minuts abans de l'enviament. Els altres controls automàtics demanen el mateix rigor, com ITMS-90725 per a la versió de Xcode o ITMS-90683 per a les frases de permís. El recorregut complet del build a l'enviament, sense Mac, és a publicar una app iOS sense Mac.
Els rebutjos d'un revisor demanen més perspectiva: el procediment és a la pàgina app rebutjada per Apple, i els motius més freqüents són a per què Apple rebutja una app.
Per revisar el teu projecte abans de l'enviament, el Review Kit reuneix la meva checklist i skills de Claude Code que repassen el teu projecte. Si l'enviament s'encalla i vols una mirada humana, reserva una hora amb mi: revisem el teu projecte per videotrucada, a la teva pantalla. I si prepares el teu primer llançament, fes el teu diagnòstic gratuït: posa els passos en ordre i t'envia la meva checklist antirebuig d'Apple.
Preguntes freqüents
ITMS-90034 és un rebuig d'App Review?
No. És una validació automàtica que es fa en enviar el build, abans de TestFlight i abans de qualsevol revisió. Ningú no ha obert la teva app: Apple només ha constatat que la signatura no prové d'un certificat de distribució vàlid.
Cal revocar el certificat de distribució per corregir ITMS-90034?
Només si està compromès o ja no és vàlid. Revocar un certificat que funciona invalida els teus perfils sense corregir la causa. Comença llegint la signatura de la IPA amb codesign i després corregeix el que assenyali l'arbre de decisió.
Es pot corregir ITMS-90034 amb una actualització remota?
No. La signatura forma part del binari, i el build rebutjat no es podrà fer servir mai. Cal generar un binari nou ben signat i tornar-lo a enviar.
Per què l'error cita el meu widget i no la meva app?
Perquè el widget és un bundle a part, signat amb el seu propi perfil. Si no està declarat a EAS o s'ha signat d'una altra manera, fa fallar tot l'enviament. Declara l'extensió a la configuració i torna a fer un build.
Què faig si codesign diu que tot és vàlid?
Comprova també el perfil inclòs i cada extensió. Si tot està net, reenvia una vegada amb un número de build nou. Si l'error persisteix, envia un informe a Apple amb la IPA, la sortida de codesign i els registres d'enviament.

