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

> 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.

Pàgina original: [ITMS-90034: corregir «Missing or invalid signature»](https://devoria.fr/ca/blog/itms-90034-missing-invalid-signature)
Autor: [Mehdi Azizi](https://devoria.fr/ca/mehdi-azizi)
Publicació: 2026-11-04
Darrera revisió del contingut: 2026-11-04


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

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

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

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

Són les ordres de [la nota TN3125 sobre els perfils](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles). 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?**

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

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

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

### 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](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes). 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](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-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](https://devoria.fr/ca/blog/clau-api-secreta-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](https://devoria.fr/ca/blog/itms-90725-sdk-version-issue-expo) per a la versió de Xcode o [ITMS-90683](https://devoria.fr/ca/blog/itms-90683-missing-purpose-string-expo) 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](https://devoria.fr/ca/blog/publicar-app-ios-sense-mac-expo-eas).

Els rebutjos d'un revisor demanen més perspectiva: el procediment és a la pàgina [app rebutjada per Apple](https://devoria.fr/ca/expertise/aplicacio-rebutjada-per-apple), i els motius més freqüents són a [per què Apple rebutja una app](https://devoria.fr/ca/blog/rebuig-apple-per-que-rebutgen-app).

Per revisar el teu projecte abans de l'enviament, el [Review Kit](https://devoria.fr/ca/kits/app-review) 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](https://devoria.fr/ca/coaching): 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](https://devoria.fr/ca/diagnostic): 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.


## El teu projecte

[Review Kit](https://devoria.fr/ca/kits/app-review): La meva checklist de revisió de l'App Store, els rebutjos d'Apple que he corregit, la de Google Play i tres skills de Claude Code. 49 €.

[iOS & Android Kit](https://devoria.fr/ca/kits/ios): Crea la teva app d'iPhone i Android amb Claude Code: el codi de partida de les meves apps, el camí fins a les botigues i tots els kits. 99 €.

[Diagnòstic: què et separa de la teva app d'iPhone](https://devoria.fr/ca/diagnostic): 7 preguntes, 60 segons: sabràs què et bloqueja de debò per publicar la teva app d'iPhone, el teu recorregut en 4 etapes i el kit que et toca.
