ITMS-90034: “Missing or invalid signature” oplossen
Door Mehdi Azizi
Gepubliceerd op , 8 min
ITMS-90034: je build is niet ondertekend met een geldig distributiecertificaat. Lees de handtekening met codesign en maak een nieuwe store-build met EAS.
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. 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 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?
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 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?
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?
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. 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?
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:
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 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:
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 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 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.
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 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.
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.
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 voor de Xcode-versie of ITMS-90683 voor de toestemmingsteksten. Het complete traject van build tot upload, zonder Mac, staat in een iOS-app publiceren zonder Mac.
Afwijzingen door een reviewer vragen meer afstand: de aanpak staat op de pagina app afgewezen door Apple, en de meest voorkomende redenen in waarom Apple je app afwijst.
Om je dossier vóór het insturen te controleren, bundelt de Review Kit 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: we lopen je project via een videogesprek door, op jouw scherm. En bereid je je eerste release voor, doe dan je gratis diagnose: 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.

