# ITMS-90034: “Missing or invalid signature” oplossen

> ITMS-90034: je build is niet ondertekend met een geldig distributiecertificaat. Lees de handtekening met codesign en maak een nieuwe store-build met EAS.

Originele pagina: [ITMS-90034: “Missing or invalid signature” oplossen](https://devoria.fr/nl/blog/itms-90034-missing-invalid-signature-oplossen)
Auteur: [Mehdi Azizi](https://devoria.fr/nl/mehdi-azizi)
Publicatie: 2026-11-04
Laatste inhoudsrevisie: 2026-11-04


ITMS-90034 krijg je als je je build naar App Store Connect stuurt. De melding zegt dat je app, of een van de onderdelen ervan, niet is ondertekend met een Apple-indieningscertificaat, oftewel een geldig distributiecertificaat. **De oplossing: zoek uit welke bundle verkeerd is ondertekend en waarom, en maak dan een nieuwe build die voor de App Store is ondertekend.**

Deze gids gaat alleen over de foutmelding. Zijn de woorden certificaat en profiel je nog vaag? Lees dan eerst [iOS-ontwikkelaarscertificaat en provisioning profile](https://devoria.fr/nl/blog/ios-certificaat-provisioning-profile-expo). Hier vind je hoe je de melding leest, een beslisboom, de commando's om je IPA te inspecteren en de oplossing met de credentials die EAS beheert. Voor het EAS-deel heb ik de code van EAS CLI 24.10.0 gelezen die het certificaat kiest.

## Wat betekent de foutmelding ITMS-90034?

Zo ziet hij er meestal uit, met voorbeeldnamen:

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

In 2026 duikt hij op het forum van Apple ook op als "Validation failed (409) Missing or invalid signature", gevolgd door dezelfde tekst en "(ID: 90034)".

Het "submission certificate" is het distributiecertificaat. [De hulppagina van Apple over certificaten](https://developer.apple.com/help/account/certificates/certificates-overview) zegt het zo: ontwikkelcertificaten gebruik je om je app op je eigen toestellen te draaien, distributiecertificaten om hem te verspreiden of naar App Store Connect te sturen.

**Lees het genoemde pad: dat wijst de schuldige bundle aan.** `Payload/MyApp.app` gaat over de app zelf. Een pad dat eindigt op `.appex` gaat over een extensie, zoals een widget. Een pad op `.framework` gaat over een ingebouwde bibliotheek.

Dit is geen afwijzing door een reviewer. De validatie gebeurt bij het uploaden of tijdens het verwerken van de build, vóór TestFlight: deze build bereikt je testers nooit.

## De beslisboom: van melding naar oplossing

Elke regel hoort bij een aanwijzing die je leest in de melding, in de commando's uit de volgende sectie of in de logs van EAS. Loop ze op volgorde af: de eerste die klopt, geeft je spoor.

| Wat je ziet                   | Waarschijnlijke oorzaak       | Oplossing                  |
| ----------------------------- | ----------------------------- | -------------------------- |
| Pad op `.appex`               | Extensie verkeerd ondertekend | Extensie declareren        |
| `Signature=adhoc`             | Build niet ondertekend        | Build met store-profiel    |
| `Apple Development`           | Development-build             | Build met store-profiel    |
| `ProvisionedDevices` gevonden | Interne build (ad hoc)        | Build met store-profiel    |
| `sealed resource`             | IPA achteraf aangepast        | Build opnieuw maken        |
| EAS: "no longer valid"        | Certificaat ingetrokken       | Nieuw certificaat          |
| Alles is geldig               | Storing bij Apple             | Opnieuw sturen, dan melden |

## Je IPA inspecteren in vier commando's

Download de IPA vanaf de buildpagina op expo.dev en open een terminal op je Mac.

**1. Wie heeft de app ondertekend?**

```bash
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
```

`codesign` schrijft naar de foutuitvoer, vandaar de `2>&1`. Volgens [technische notitie TN3161 van Apple](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates) is elke regel `Authority` een schakel in de vertrouwensketen. De eerste moet beginnen met `Apple Distribution:` of `iPhone Distribution:`, gevolgd door de naam van je team. Het tweede label hoort bij het oude type iOS Distribution: volgens de code maakt EAS CLI 24.10.0 nog steeds certificaten van dat type. Lees je `Apple Development:`, dan is het een development-build. Lees je `Signature=adhoc` zonder enige regel `Authority`, dan is de binary door geen enkel certificaat ondertekend.

**2. Is de app na het ondertekenen aangepast?**

```bash
codesign --verify --deep --strict -vv ipa/Payload/*.app
```

Je wilt `valid on disk` zien, en daarna `satisfies its Designated Requirement`. TN3161 legt uit wat deze controle garandeert: alle verwachte bestanden zijn er, er is niets toegevoegd en niets aangepast. Op een testbundle die ik had ondertekend en daarna had bewerkt, antwoordt het commando `a sealed resource is missing or invalid`, gevolgd door `file modified:` en het gewijzigde bestand. De optie `--deep` gebruik je hier om te controleren, nooit om te ondertekenen: op het forum van Apple raadt een engineer van het supportteam dat af voor ondertekenen.

**3. Welk profiel zit erin?**

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

Dit zijn de commando's uit [notitie TN3125 over profielen](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles). Een App Store-profiel bevat geen lijst met toestellen: de tweede regel moet `Could not extract value` teruggeven. Zie je toestel-ID's, dan is het een ad-hocprofiel, dat van een interne build. De derde regel geeft de vervaldatum van het profiel.

**4. Zijn de extensies en frameworks op dezelfde manier ondertekend?**

```bash
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
  -exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
```

Elk onderdeel moet dezelfde regel `Authority` tonen als de app. Wijkt er een af, dan is dat het onderdeel dat in de melding staat.

Wil je het vóór het uploaden controleren? TN3161 raadt `altool` aan, dezelfde controle als de knop Validate App in Xcode. Daarvoor heb je een App Store Connect API-sleutel nodig, waarvan het bestand `AuthKey_<KEY_ID>.p8` in `~/.appstoreconnect/private_keys` hoort:

```bash
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
```

## Oplossen met EAS, oorzaak per oorzaak

### Een interne of development-build naar Apple gestuurd

Volgens de [documentatie van Expo over eas.json](https://docs.expo.dev/build/eas-json/) worden builds met `"distribution": "internal"` niet voor de stores ondertekend: ze gebruiken een ad-hocprofiel. Alleen een profiel met distributie `store`, de standaardwaarde, levert een build op die je kunt insturen. **Het veiligst is de build insturen die je net hebt gemaakt, zonder hem met de hand te kiezen**:

```bash
eas build --platform ios --profile production --auto-submit
```

Gebruik je `eas submit --path`? Controleer dan of het bestand echt je laatste store-build is. Op het forum van Apple ontdekte een team dat hun uploadtool elke keer een oude IPA instuurde die in git stond.

### Een vergeten extensie

Elke extensie is een aparte bundle, met een eigen identifier en een eigen profiel. In een Expo-project met native generatie vraagt de [pagina van Expo over iOS-extensies](https://docs.expo.dev/build-reference/app-extensions/) om ze te declareren in `extra.eas.build.experimental.ios.appExtensions`. EAS CLI kent ze dan vóór de build en maakt of valideert hun credentials. De meeste bibliotheken die een extensie toevoegen, schrijven die declaratie via hun plugin voor je.

Solys, mijn wekker met minigames, bevat vier extensies: een widget en drie Screen Time-extensies. Alle vier staan in de configuratie gedeclareerd, en EAS heeft voor elk een profiel. **Een extensie die je met de hand in Xcode hebt toegevoegd, zonder die declaratie, is de ideale kandidaat** voor een pad op `.appex` in de melding.

### Een ingetrokken of verlopen certificaat

De [pagina van Apple over certificaten](https://developer.apple.com/support/certificates/) is duidelijk: je kunt geen build meer insturen die is ondertekend met een verlopen of ingetrokken certificaat. Een build die al is geüpload maar nog niet ingediend, kan zelfs op Invalid Binary komen te staan als het certificaat is ingetrokken.

De code van EAS CLI 24.10.0 laat zien wanneer dit ongemerkt blijft:

- **Interactieve build, ingelogd bij Apple**: EAS vergelijkt het certificaat met de certificaten die bij Apple nog geldig zijn. Staat het er niet meer bij, dan toont het "Current distribution certificate is no longer valid in Apple Dev Portal" en laat het je er een kiezen of aanmaken.
- **Interactieve build, niet ingelogd**: EAS controleert alleen de datums en waarschuwt dat het de validatie bij Apple overslaat.
- **Niet-interactieve build, in CI**: EAS toont "Distribution Certificate is not validated for non-interactive builds" en ondertekent toch.

**In CI controleert EAS het certificaat zelf niet opnieuw: een intrekking zie je misschien pas bij het uploaden.** De oplossing: start een interactieve build terwijl je bent ingelogd op je Apple-account, of gebruik `eas credentials --platform ios`, menu Build Credentials, en dan "Distribution Certificate: Add a new one to your account". De profielen met het oude certificaat worden ongeldig: EAS controleert ze bij de volgende build en maakt ze opnieuw. De limieten van Apple op het aantal certificaten staan in de [gids over het iOS-ontwikkelaarscertificaat](https://devoria.fr/nl/blog/ios-certificaat-provisioning-profile-expo).

### Een binary die na het ondertekenen is aangepast

De handtekening verzegelt de code, de resources en de metadata met hashes, zoals [notitie TN3126 van Apple](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes) uitlegt. De IPA uitpakken om een bestand te wijzigen en hem daarna weer inpakken, verbreekt dat zegel. **Doe de aanpassing in je configuratie en maak een nieuwe build.** Bewerk nooit de IPA die EAS heeft gemaakt.

Hetzelfde geldt voor code op de verkeerde plek, bijvoorbeeld in een `.zip`-archief: de App Store kan die niet opnieuw ondertekenen. Apple beschrijft de toegestane plekken op de pagina over [de inhoud van een bundle](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle).

### Lokale credentials

Gebruikt je EAS-profiel `"credentialsSource": "local"`, dan verwijst je bestand `credentials.json` naar een `.p12`-certificaat en een `.mobileprovision`-profiel. Controleer het profiel met de commando's uit stap 3: het moet van het type App Store zijn en je huidige distributiecertificaat bevatten. En houd die bestanden buiten je repository, net als [de API-sleutels van een Expo-app](https://devoria.fr/nl/blog/geheime-api-sleutel-expo-app-beschermen).

### Als alles geldig is

Er blijft één frustrerend geval over. Op het forum van Apple zien ontwikkelaars de fout verdwijnen door dezelfde build opnieuw te sturen, zonder iets te veranderen. In augustus en september 2026 beschrijven twee topics het omgekeerde: nieuw certificaat en profiel, handtekening gecontroleerd, en toch blijft het misgaan. In een daarvan raadt een engineer van Apple een bugrapport aan met de IPA, de analyse van de handtekening en de logs van Transporter, en daarna contact met App Store Connect.

Stuur dus één keer opnieuw met een nieuw buildnummer. Komt de fout terug terwijl je vier commando's schoon zijn, meld het dan bij Apple met die gegevens. **Trek je certificaat niet uit reflex in**: dat lost niets extra op en maakt je profielen ongeldig.

## Je build insturen zonder vervelende verrassingen

Een handtekening controleer je in twee minuten vóór het uploaden. De andere automatische controles vragen dezelfde zorgvuldigheid, zoals [ITMS-90725](https://devoria.fr/nl/blog/itms-90725-sdk-version-issue-expo) voor de Xcode-versie of [ITMS-90683](https://devoria.fr/nl/blog/itms-90683-missing-purpose-string-expo) voor de toestemmingsteksten. Het complete traject van build tot upload, zonder Mac, staat in [een iOS-app publiceren zonder Mac](https://devoria.fr/nl/blog/ios-app-publiceren-zonder-mac-expo-eas).

Afwijzingen door een reviewer vragen meer afstand: de aanpak staat op de pagina [app afgewezen door Apple](https://devoria.fr/nl/expertise/app-afgewezen-door-apple), en de meest voorkomende redenen in [waarom Apple je app afwijst](https://devoria.fr/nl/blog/app-afgewezen-door-apple-waarom).

Om je dossier vóór het insturen te controleren, bundelt de [Review Kit](https://devoria.fr/nl/kits/app-review) mijn checklist en Claude Code-skills die je project nalopen. Loopt je upload vast en wil je een menselijke blik, [boek een uur met mij](https://devoria.fr/nl/coaching): we lopen je project via een videogesprek door, op jouw scherm. En bereid je je eerste release voor, [doe dan je gratis diagnose](https://devoria.fr/nl/diagnostic): die zet de stappen op volgorde en stuurt je mijn checklist tegen afwijzingen door Apple.

## Veelgestelde vragen

### Is ITMS-90034 een afwijzing door App Review?

Nee. Het is een automatische validatie bij het uploaden van de build, vóór TestFlight en vóór elke review. Niemand heeft je app geopend: Apple heeft alleen vastgesteld dat de handtekening niet van een geldig distributiecertificaat komt.

### Moet ik mijn distributiecertificaat intrekken om ITMS-90034 op te lossen?

Alleen als het gecompromitteerd of al ongeldig is. Een werkend certificaat intrekken maakt je profielen ongeldig zonder de oorzaak op te lossen. Lees eerst de handtekening van je IPA met `codesign` en los dan op wat de beslisboom aanwijst.

### Kun je ITMS-90034 oplossen met een update op afstand?

Nee. De handtekening hoort bij de binary, en de afgewezen build is nooit bruikbaar. Je moet een nieuwe, correct ondertekende binary maken en die opnieuw insturen.

### Waarom noemt de melding mijn widget en niet mijn app?

Omdat de widget een aparte bundle is, ondertekend met een eigen profiel. Is hij niet bij EAS gedeclareerd of anders ondertekend, dan laat hij de hele upload mislukken. Declareer de extensie in je configuratie en maak een nieuwe build.

### Wat moet ik doen als codesign zegt dat alles geldig is?

Controleer ook het ingebouwde profiel en elke extensie. Is alles schoon, stuur dan één keer opnieuw met een nieuw buildnummer. Blijft de fout, stuur Apple een rapport met de IPA, de uitvoer van `codesign` en de uploadlogs.


## Je project

[Review Kit](https://devoria.fr/nl/kits/app-review): Mijn App Store-reviewchecklist, mijn opgeloste afwijzingen door Apple, die voor Google Play en drie Claude Code-skills. € 49.

[iOS & Android Kit](https://devoria.fr/nl/kits/ios): Bouw je iPhone- en Android-app met Claude Code: de startcode van mijn apps, de route naar de stores en alle kits. € 99.

[Diagnose: wat staat er tussen jou en je iPhone-app](https://devoria.fr/nl/diagnostic): 7 vragen, 60 seconden: je weet wat je echt tegenhoudt om je iPhone-app te publiceren, je traject in 4 stappen en de kit die bij je past.
