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

> ITMS-90034: build kamu tidak ditandatangani sertifikat distribusi yang valid. Cek dengan codesign, lalu build ulang untuk App Store lewat EAS.

Halaman asli: [ITMS-90034: mengatasi “Missing or invalid signature”](https://devoria.fr/id/blog/itms-90034-missing-invalid-signature)
Penulis: [Mehdi Azizi](https://devoria.fr/id/mehdi-azizi)
Terbit: 2026-11-04
Revisi konten terakhir: 2026-11-04


ITMS-90034 muncul saat kamu mengirim build ke App Store Connect. Artinya, app kamu atau salah satu komponennya tidak ditandatangani dengan sertifikat submission Apple, yaitu sertifikat distribusi yang valid. **Solusinya: cari bundle mana yang salah tanda tangan dan kenapa, lalu buat ulang build yang ditandatangani untuk App Store.**

Panduan ini fokus pada error-nya saja. Kalau istilah sertifikat dan profile masih membingungkan, baca dulu [sertifikat developer iOS dan provisioning profile](https://devoria.fr/id/blog/sertifikat-developer-ios-provisioning-profile-expo). Di sini kamu akan menemukan pesan yang perlu dibaca, pohon keputusan, perintah untuk memeriksa IPA kamu, dan perbaikannya dengan kredensial yang dikelola EAS. Untuk bagian EAS, saya membaca kode EAS CLI 24.10.0 yang memilih sertifikat.

## Apa arti error ITMS-90034?

Ini bentuk klasiknya, dengan nama contoh:

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

Di tahun 2026, di forum Apple, error ini juga muncul dalam bentuk "Validation failed (409) Missing or invalid signature", diikuti teks yang sama dan "(ID: 90034)".

"Sertifikat submission" itu adalah sertifikat distribusi. [Bantuan Apple tentang sertifikat](https://developer.apple.com/help/account/certificates/certificates-overview) menjelaskannya: sertifikat development dipakai untuk menjalankan app di perangkat kamu, sertifikat distribusi untuk mendistribusikannya atau mengirimnya ke App Store Connect.

**Baca path yang disebut: path itu menunjuk bundle yang bermasalah.** `Payload/MyApp.app` menunjuk app itu sendiri. Path yang berakhiran `.appex` menunjuk extension, misalnya widget. Path berakhiran `.framework` menunjuk library yang di-embed.

Ini bukan penolakan dari reviewer. Validasi gagal saat pengiriman atau saat build diproses, sebelum TestFlight: build ini tidak akan pernah sampai ke tester kamu.

## Pohon keputusan: dari pesan ke perbaikan

Setiap baris sesuai dengan petunjuk yang kamu baca di pesan error, di perintah pada bagian berikutnya, atau di log EAS. Periksa secara berurutan: baris pertama yang cocok adalah petunjuk kamu.

| Yang kamu lihat          | Kemungkinan penyebab         | Perbaikan                  |
| ------------------------ | ---------------------------- | -------------------------- |
| Path berakhiran `.appex` | Extension salah tanda tangan | Deklarasikan extension     |
| `Signature=adhoc`        | Build tidak ditandatangani   | Build dengan profile store |
| `Apple Development`      | Build development            | Build dengan profile store |
| `ProvisionedDevices` ada | Build internal (ad hoc)      | Build dengan profile store |
| `sealed resource`        | IPA diubah setelah build     | Build ulang                |
| EAS: "no longer valid"   | Sertifikat dicabut           | Sertifikat baru            |
| Semuanya valid           | Masalah di sisi Apple        | Kirim ulang, lalu laporkan |

## Memeriksa IPA kamu dengan empat perintah

Unduh IPA dari halaman build di expo.dev, lalu buka terminal di Mac kamu.

**1. Siapa yang menandatangani app?**

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

`codesign` menulis ke output error, makanya ada `2>&1`. Menurut [catatan teknis TN3161 dari Apple](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates), setiap baris `Authority` adalah satu mata rantai dalam rantai kepercayaan. Baris pertama harus diawali `Apple Distribution:` atau `iPhone Distribution:`, diikuti nama tim kamu. Label kedua adalah label untuk tipe lama iOS Distribution: menurut kodenya, EAS CLI 24.10.0 masih membuat sertifikat dengan tipe ini. Kalau kamu membaca `Apple Development:`, itu build development. Kalau kamu membaca `Signature=adhoc` tanpa satu pun baris `Authority`, binary-nya tidak ditandatangani sertifikat apa pun.

**2. Apakah app diubah setelah ditandatangani?**

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

Yang kamu harapkan adalah `valid on disk`, lalu `satisfies its Designated Requirement`. TN3161 menjelaskan apa yang dijamin oleh pemeriksaan ini: semua file yang diharapkan ada, tidak ada yang ditambahkan, tidak ada yang diubah. Pada bundle uji yang saya tandatangani lalu saya utak-atik, perintah ini menjawab `a sealed resource is missing or invalid`, lalu `file modified:` diikuti file yang berubah. Opsi `--deep` di sini dipakai untuk memeriksa, jangan pernah untuk menandatangani: di forum Apple, seorang engineer dari tim support tidak menyarankannya untuk menandatangani.

**3. Profile mana yang di-embed?**

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

Ini perintah dari [catatan TN3125 tentang profile](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles). Profile App Store tidak berisi daftar perangkat: baris kedua harus menjawab `Could not extract value`. Kalau baris itu menampilkan ID perangkat, itu profile ad hoc, milik build internal. Baris ketiga memberi tanggal kedaluwarsa profile.

**4. Apakah extension dan framework ditandatangani dengan cara yang sama?**

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

Setiap komponen harus menampilkan baris `Authority` yang sama dengan app. Kalau ada yang berbeda, komponen itulah yang disebut dalam pesan error.

Kalau kamu ingin memeriksa sebelum mengirim, TN3161 merekomendasikan `altool`, pemeriksaan yang sama dengan tombol Validate App di Xcode. Perintah ini butuh API key App Store Connect, yang file `AuthKey_<KEY_ID>.p8`-nya disimpan di `~/.appstoreconnect/private_keys`:

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

## Memperbaiki dengan EAS, per penyebab

### Build internal atau development yang dikirim ke Apple

Menurut [dokumentasi Expo tentang eas.json](https://docs.expo.dev/build/eas-json/), build dengan `"distribution": "internal"` tidak ditandatangani untuk store: build ini memakai profile ad hoc. Hanya profile dengan distribusi `store`, nilai default-nya, yang menghasilkan build yang bisa dikirim. **Cara paling aman adalah mengirim build yang baru saja kamu buat, tanpa memilihnya secara manual**:

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

Kalau kamu memakai `eas submit --path`, pastikan file-nya memang build store terakhir kamu. Di forum Apple, sebuah tim mendapati bahwa tool pengiriman mereka selalu mengirim IPA lama yang tersimpan di git.

### Extension yang terlupakan

Setiap extension adalah bundle tersendiri, dengan identifier dan profile-nya sendiri. Di proyek Expo yang native-nya di-generate, [halaman Expo tentang extension iOS](https://docs.expo.dev/build-reference/app-extensions/) meminta kamu mendeklarasikannya di `extra.eas.build.experimental.ios.appExtensions`. Dengan begitu EAS CLI mengenalinya sebelum build, lalu membuat atau memvalidasi kredensialnya. Sebagian besar library yang menambahkan extension menuliskan deklarasi ini untuk kamu, lewat plugin-nya.

Solys, aplikasi alarm saya dengan mini-game, membawa empat extension: satu widget dan tiga extension Screen Time. Keempatnya dideklarasikan di konfigurasinya, dan EAS punya profile untuk masing-masing. **Extension yang ditambahkan manual di Xcode, tanpa deklarasi ini, adalah tersangka utama** untuk path berakhiran `.appex` di pesan error.

### Sertifikat dicabut atau kedaluwarsa

[Halaman Apple tentang sertifikat](https://developer.apple.com/support/certificates/) jelas: kamu tidak bisa lagi mengirim build yang ditandatangani dengan sertifikat yang kedaluwarsa atau dicabut. Build yang sudah dikirim tapi belum di-submit bahkan bisa berubah menjadi Invalid Binary kalau sertifikatnya dicabut.

Kode EAS CLI 24.10.0 menunjukkan kapan kasus ini tidak terdeteksi:

- **Build interaktif, terhubung ke Apple**: EAS membandingkan sertifikatnya dengan sertifikat yang masih valid di Apple. Kalau sudah tidak ada, EAS menampilkan "Current distribution certificate is no longer valid in Apple Dev Portal" dan menawarkan untuk memilih atau membuat yang baru.
- **Build interaktif, tanpa login**: EAS hanya memeriksa tanggal dan memberi tahu bahwa ia melewati validasi di Apple.
- **Build non-interaktif, di continuous integration**: EAS menampilkan "Distribution Certificate is not validated for non-interactive builds" dan tetap menandatangani.

**Di continuous integration, EAS tidak memeriksa ulang sertifikatnya sendiri: pencabutan bisa saja baru ketahuan saat pengiriman.** Solusinya: jalankan build interaktif yang terhubung ke akun Apple kamu, atau lewat `eas credentials --platform ios`, menu Build Credentials, lalu "Distribution Certificate: Add a new one to your account". Profile yang berisi sertifikat lama menjadi tidak valid: EAS memeriksanya di build berikutnya dan membuatnya ulang. Batasan Apple soal jumlah sertifikat dijelaskan di [panduan sertifikat developer iOS](https://devoria.fr/id/blog/sertifikat-developer-ios-provisioning-profile-expo).

### Binary diubah setelah ditandatangani

Tanda tangan menyegel kode, resource, dan metadata dengan hash, seperti dijelaskan [catatan TN3126 dari Apple](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes). Mengekstrak IPA untuk mengubah satu file lalu mengompresnya lagi akan merusak segel itu. **Lakukan perubahan di konfigurasi kamu, lalu build ulang.** Jangan pernah mengutak-atik IPA yang dihasilkan EAS.

Logikanya sama untuk kode yang disimpan di tempat yang salah, misalnya di dalam arsip `.zip`: App Store tidak bisa menandatanganinya ulang. Apple menjelaskan lokasi yang diizinkan di halaman tentang [isi sebuah bundle](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle).

### Kredensial lokal

Kalau profile EAS kamu memakai `"credentialsSource": "local"`, file `credentials.json` kamu menunjuk ke sertifikat `.p12` dan profile `.mobileprovision`. Periksa profile-nya dengan perintah di langkah 3: tipenya harus App Store dan berisi sertifikat distribusi kamu yang sekarang. Dan simpan file-file ini di luar repo, seperti [API key di app Expo](https://devoria.fr/id/blog/kunci-api-rahasia-aplikasi-expo).

### Kalau semuanya valid

Masih ada satu kasus yang bikin frustrasi. Di forum Apple, beberapa developer melihat error ini hilang hanya dengan mengirim ulang build yang sama, tanpa mengubah apa pun. Di bulan Agustus dan September 2026, dua thread menggambarkan kebalikannya: sertifikat dan profile baru, tanda tangan sudah dicek, tetap gagal. Di salah satunya, seorang engineer Apple menyarankan bug report berisi IPA, analisis tanda tangan, dan log Transporter, lalu menghubungi App Store Connect.

Jadi kirim ulang sekali dengan build number baru. Kalau error muncul lagi padahal keempat perintah kamu bersih, laporkan ke Apple dengan bahan-bahan tersebut. **Jangan refleks mencabut sertifikat kamu**: itu tidak menyelesaikan apa-apa dan malah membuat profile kamu tidak valid.

## Mengirim build tanpa kejutan

Tanda tangan bisa dicek dalam dua menit sebelum pengiriman. Pemeriksaan otomatis lainnya juga butuh ketelitian yang sama, seperti [ITMS-90725](https://devoria.fr/id/blog/itms-90725-sdk-version-issue-expo) untuk versi Xcode atau [ITMS-90683](https://devoria.fr/id/blog/itms-90683-missing-purpose-string-expo) untuk kalimat izin. Alur lengkap dari build sampai pengiriman, tanpa Mac, ada di [publikasi app iOS tanpa Mac](https://devoria.fr/id/blog/publish-aplikasi-ios-tanpa-mac-expo-eas).

Penolakan dari reviewer butuh pendekatan yang lebih matang: langkah-langkahnya ada di halaman [aplikasi ditolak Apple](https://devoria.fr/id/expertise/aplikasi-ditolak-apple), dan alasan yang paling sering ada di [kenapa Apple menolak app](https://devoria.fr/id/blog/aplikasi-ditolak-apple-penyebab-solusi).

Untuk memeriksa berkas kamu sebelum pengiriman, [Review Kit](https://devoria.fr/id/kits/app-review) berisi checklist saya dan skill Claude Code yang membaca ulang proyek kamu. Kalau pengiriman kamu macet dan kamu ingin dilihat langsung oleh manusia, [booking satu jam dengan saya](https://devoria.fr/id/coaching): kita bahas proyek kamu lewat video call, di layar kamu. Dan kalau kamu sedang menyiapkan rilis pertama, [ikuti diagnostic gratis](https://devoria.fr/id/diagnostic): diagnostic ini menyusun langkah-langkahnya secara berurutan dan mengirimkan checklist anti-penolakan Apple saya.

## Pertanyaan umum

### Apakah ITMS-90034 penolakan dari App Review?

Bukan. Ini validasi otomatis saat build dikirim, sebelum TestFlight dan sebelum review apa pun. Tidak ada yang membuka app kamu: Apple hanya mendapati bahwa tanda tangannya tidak berasal dari sertifikat distribusi yang valid.

### Apakah saya harus mencabut sertifikat distribusi untuk memperbaiki ITMS-90034?

Hanya kalau sertifikatnya bocor atau memang sudah tidak valid. Mencabut sertifikat yang berfungsi akan membuat profile kamu tidak valid tanpa memperbaiki penyebabnya. Mulailah dengan membaca tanda tangan IPA kamu dengan `codesign`, lalu perbaiki apa yang ditunjuk pohon keputusan.

### Bisakah ITMS-90034 diperbaiki dengan update jarak jauh?

Tidak. Tanda tangan adalah bagian dari binary, dan build yang ditolak tidak akan pernah bisa dipakai. Kamu harus membuat binary baru yang ditandatangani dengan benar lalu mengirimnya ulang.

### Kenapa error-nya menyebut widget saya, bukan app saya?

Karena widget adalah bundle tersendiri, ditandatangani dengan profile-nya sendiri. Kalau tidak dideklarasikan ke EAS atau ditandatangani dengan cara lain, widget itu menggagalkan seluruh pengiriman. Deklarasikan extension di konfigurasi kamu dan build ulang.

### Apa yang harus dilakukan kalau codesign bilang semuanya valid?

Periksa juga profile yang di-embed dan setiap extension. Kalau semuanya bersih, kirim ulang sekali dengan build number baru. Kalau error tetap muncul, kirim laporan ke Apple berisi IPA, output `codesign`, dan log pengiriman.


## Proyekmu

[Review Kit](https://devoria.fr/id/kits/app-review): Checklist review App Store saya, penolakan Apple yang sudah saya perbaiki, checklist Google Play, dan tiga skill Claude Code. Rp 999.000.

[iOS & Android Kit](https://devoria.fr/id/kits/ios): Bikin app iPhone dan Android kamu dengan Claude Code: kode awal dari app-app saya, langkah demi langkah sampai ke store, dan semua kit. Rp 1.999.000.

[Diagnosis: apa yang memisahkanmu dari app iPhone-mu](https://devoria.fr/id/diagnostic): 7 pertanyaan, 60 detik: kamu tahu apa yang benar-benar menghambatmu merilis app iPhone, jalurmu dalam 4 tahap, dan kit yang cocok untukmu.
