# ITMS-90034 แก้ Missing or invalid signature บน iOS

> ITMS-90034 แปลว่า build ของคุณไม่ได้เซ็นด้วยใบรับรอง distribution ที่ใช้ได้ ตรวจลายเซ็นด้วย codesign แล้วสร้าง build แบบ store ใหม่ด้วย EAS

หน้าต้นฉบับ: [ITMS-90034 แก้ Missing or invalid signature บน iOS](https://devoria.fr/th/blog/itms-90034-missing-or-invalid-signature-fix)
ผู้เขียน: [Mehdi Azizi](https://devoria.fr/th/mehdi-azizi)
เผยแพร่: 2026-11-04
แก้ไขเนื้อหาล่าสุด: 2026-11-04


ITMS-90034 จะขึ้นตอนที่คุณส่ง build ไปยัง App Store Connect ข้อความนี้บอกว่าแอปของคุณ หรือส่วนประกอบใดส่วนหนึ่งของแอป ไม่ได้เซ็นด้วยใบรับรองสำหรับส่งแอปของ Apple (Apple submission certificate) ซึ่งก็คือใบรับรอง distribution ที่ยังใช้ได้ **วิธีแก้คือ หาให้เจอว่า bundle ไหนเซ็นผิดและผิดเพราะอะไร แล้วสร้าง build ใหม่ที่เซ็นสำหรับ App Store**

คู่มือนี้จะพูดถึงแค่ error ตัวนี้ ถ้าคุณยังไม่ค่อยเข้าใจคำว่าใบรับรองกับโปรไฟล์ แนะนำให้อ่าน [ใบรับรองนักพัฒนา iOS และ provisioning profile](https://devoria.fr/th/blog/ios-certificate-provisioning-profile-expo) ก่อน ในบทความนี้คุณจะได้รู้ว่าต้องอ่านข้อความตรงไหน มีแผนผังการตัดสินใจ มีคำสั่งสำหรับตรวจไฟล์ IPA และวิธีแก้ด้วยข้อมูลรับรองที่ EAS จัดการให้ ในส่วนของ EAS ผมไปอ่านโค้ดของ EAS CLI 24.10.0 ตรงส่วนที่เลือกใบรับรองมาแล้ว

## error ITMS-90034 หมายความว่าอะไร?

หน้าตาปกติของมันเป็นแบบนี้ (ใช้ชื่อตัวอย่าง):

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

ในปี 2026 บนฟอรัมของ Apple ยังเจอในรูป "Validation failed (409) Missing or invalid signature" ตามด้วยข้อความเดียวกันและ "(ID: 90034)" ด้วย

"ใบรับรองสำหรับส่งแอป" ก็คือใบรับรอง distribution นั่นเอง [หน้าช่วยเหลือของ Apple เรื่องใบรับรอง](https://developer.apple.com/help/account/certificates/certificates-overview) เขียนไว้ว่า ใบรับรอง development ใช้รันแอปบนอุปกรณ์ของคุณ ส่วนใบรับรอง distribution ใช้แจกจ่ายแอปหรือส่งไปยัง App Store Connect

**อ่าน path ที่อยู่ในข้อความให้ดี เพราะมันชี้ไปที่ bundle ที่มีปัญหา** `Payload/MyApp.app` หมายถึงตัวแอปเอง path ที่ลงท้ายด้วย `.appex` หมายถึง extension เช่น widget ส่วน path ที่ลงท้ายด้วย `.framework` หมายถึงไลบรารีที่ฝังอยู่ในแอป

นี่ไม่ใช่การปฏิเสธจาก reviewer การตรวจนี้ล้มตั้งแต่ตอนส่งหรือระหว่างประมวลผล build ก่อนถึง TestFlight build นี้จึงไม่มีวันไปถึงมือผู้ทดสอบของคุณ

## แผนผังการตัดสินใจ: จากข้อความสู่วิธีแก้

แต่ละแถวคือเบาะแสที่คุณจะเห็นในข้อความ error ในคำสั่งของหัวข้อถัดไป หรือใน log ของ EAS ไล่ดูตามลำดับ แถวแรกที่ตรงคือทางที่คุณต้องไป

| สิ่งที่คุณเห็น               | สาเหตุที่น่าจะเป็น    | วิธีแก้                 |
| ---------------------------- | --------------------- | ----------------------- |
| path ลงท้าย `.appex`         | extension เซ็นผิด     | ประกาศ extension        |
| `Signature=adhoc`            | build ไม่ได้เซ็น      | build ด้วยโปรไฟล์ store |
| `Apple Development`          | build แบบ development | build ด้วยโปรไฟล์ store |
| อ่านเจอ `ProvisionedDevices` | build ภายใน (ad hoc)  | build ด้วยโปรไฟล์ store |
| `sealed resource`            | IPA ถูกแก้หลังเซ็น    | build ใหม่              |
| EAS: "no longer valid"       | ใบรับรองถูกเพิกถอน    | สร้างใบรับรองใหม่       |
| ทุกอย่างถูกต้อง              | ปัญหาฝั่ง Apple       | ส่งใหม่ แล้วแจ้ง Apple  |

## ตรวจ IPA ของคุณด้วย 4 คำสั่ง

ดาวน์โหลดไฟล์ IPA จากหน้า build บน expo.dev แล้วเปิด terminal บน Mac ของคุณ

**1. ใครเป็นคนเซ็นแอป?**

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

`codesign` เขียนผลออกทาง standard error จึงต้องใส่ `2>&1` ตาม [technote TN3161 ของ Apple](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates) แต่ละบรรทัด `Authority` คือห่วงหนึ่งในสายความเชื่อถือ (chain of trust) บรรทัดแรกต้องขึ้นต้นด้วย `Apple Distribution:` หรือ `iPhone Distribution:` ตามด้วยชื่อทีมของคุณ แบบที่สองเป็นชื่อของใบรับรองประเภท iOS Distribution รุ่นเก่า จากโค้ดของ EAS CLI 24.10.0 มันยังสร้างใบรับรองประเภทนี้อยู่ ถ้าคุณเห็น `Apple Development:` แปลว่าเป็น build แบบ development ถ้าเห็น `Signature=adhoc` โดยไม่มีบรรทัด `Authority` เลย แปลว่าไบนารีนี้ไม่ได้เซ็นด้วยใบรับรองใดเลย

**2. แอปถูกแก้ไขหลังจากเซ็นหรือเปล่า?**

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

สิ่งที่คุณอยากเห็นคือ `valid on disk` ตามด้วย `satisfies its Designated Requirement` TN3161 อธิบายว่าการตรวจนี้รับประกันอะไร: ไฟล์ที่ควรมีอยู่ครบ ไม่มีไฟล์ไหนถูกเพิ่ม และไม่มีไฟล์ไหนถูกแก้ ผมลองกับ bundle ทดสอบที่เซ็นแล้วไปแก้ทีหลัง คำสั่งตอบกลับมาว่า `a sealed resource is missing or invalid` แล้วตามด้วย `file modified:` และชื่อไฟล์ที่ถูกแก้ ตัวเลือก `--deep` ในที่นี้ใช้สำหรับตรวจเท่านั้น ห้ามใช้ตอนเซ็น บนฟอรัมของ Apple วิศวกรของทีมซัพพอร์ตก็แนะนำว่าไม่ควรใช้มันเซ็น

**3. โปรไฟล์ที่ฝังอยู่คืออะไร?**

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

นี่คือคำสั่งจาก [technote TN3125 เรื่องโปรไฟล์](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles) โปรไฟล์ App Store จะไม่มีรายชื่ออุปกรณ์ บรรทัดที่สองจึงต้องตอบว่า `Could not extract value` ถ้ามันแสดง ID ของอุปกรณ์ออกมา แปลว่าเป็นโปรไฟล์ ad hoc ของ build ภายใน ส่วนบรรทัดที่สามจะบอกวันหมดอายุของโปรไฟล์

**4. extension และ framework เซ็นเหมือนกันหรือเปล่า?**

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

ทุกส่วนประกอบต้องแสดงบรรทัด `Authority` เหมือนกับตัวแอป ถ้ามีตัวไหนไม่ตรง ตัวนั้นแหละคือตัวที่ข้อความ error พูดถึง

ถ้าอยากตรวจก่อนส่ง TN3161 แนะนำ `altool` ซึ่งตรวจแบบเดียวกับปุ่ม Validate App ใน Xcode ต้องใช้ API key ของ App Store Connect โดยเก็บไฟล์ `AuthKey_<ID_CLE>.p8` ไว้ใน `~/.appstoreconnect/private_keys`:

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

## แก้ด้วย EAS ทีละสาเหตุ

### ส่ง build ภายในหรือ build แบบ development ไปให้ Apple

ตาม[เอกสารของ Expo เรื่อง eas.json](https://docs.expo.dev/build/eas-json/) build ที่ตั้ง `"distribution": "internal"` ไม่ได้เซ็นสำหรับ store แต่ใช้โปรไฟล์ ad hoc มีแค่โปรไฟล์ที่ตั้ง distribution เป็น `store` (ค่าเริ่มต้น) เท่านั้นที่ได้ build ซึ่งส่งได้ **วิธีที่ปลอดภัยที่สุดคือส่ง build ที่คุณเพิ่ง build เสร็จ โดยไม่ต้องเลือกเอง**:

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

ถ้าคุณใช้ `eas submit --path` ให้เช็กว่าไฟล์นั้นคือ build แบบ store ล่าสุดจริงๆ บนฟอรัมของ Apple มีทีมหนึ่งเพิ่งมารู้ว่าเครื่องมือส่งของพวกเขาส่ง IPA เก่าที่เก็บไว้ใน git ทุกครั้ง

### ลืม extension

extension แต่ละตัวเป็น bundle แยก มี identifier และโปรไฟล์ของตัวเอง ในโปรเจกต์ Expo ที่ใช้การสร้างโค้ด native อัตโนมัติ [หน้าของ Expo เรื่อง extension บน iOS](https://docs.expo.dev/build-reference/app-extensions/) ให้ประกาศไว้ใน `extra.eas.build.experimental.ios.appExtensions` แล้ว EAS CLI จะรู้จักมันตั้งแต่ก่อน build และสร้างหรือตรวจข้อมูลรับรองให้ ไลบรารีส่วนใหญ่ที่เพิ่ม extension จะเขียนการประกาศนี้ให้คุณผ่าน plugin ของมัน

Solys แอปนาฬิกาปลุกมินิเกมของผม มี extension อยู่ 4 ตัว: widget หนึ่งตัว และ extension ของ Screen Time อีกสามตัว ทั้งสี่ตัวประกาศไว้ใน config และ EAS มีโปรไฟล์ให้ทุกตัว **extension ที่เพิ่มเองใน Xcode โดยไม่ได้ประกาศไว้ คือผู้ต้องสงสัยอันดับหนึ่ง** เมื่อข้อความ error มี path ลงท้าย `.appex`

### ใบรับรองถูกเพิกถอนหรือหมดอายุ

[หน้าของ Apple เรื่องใบรับรอง](https://developer.apple.com/support/certificates/) เขียนชัดเจนว่า คุณส่ง build ที่เซ็นด้วยใบรับรองที่หมดอายุหรือถูกเพิกถอนไม่ได้ build ที่ส่งไปแล้วแต่ยังไม่ได้ส่งรีวิว ยังอาจกลายเป็นสถานะ Invalid Binary ได้ด้วยถ้าใบรับรองของมันถูกเพิกถอน

โค้ดของ EAS CLI 24.10.0 แสดงให้เห็นว่ากรณีไหนที่ปัญหานี้หลุดรอดไปได้:

- **build แบบ interactive ที่ล็อกอิน Apple ไว้**: EAS จะเทียบใบรับรองของมันกับใบรับรองที่ยังใช้ได้ฝั่ง Apple ถ้าไม่เจอ จะขึ้นว่า "Current distribution certificate is no longer valid in Apple Dev Portal" แล้วให้คุณเลือกหรือสร้างใบใหม่
- **build แบบ interactive ที่ไม่ได้ล็อกอิน**: EAS ตรวจแค่วันที่ และเตือนว่าข้ามการตรวจฝั่ง Apple ไป
- **build แบบ non-interactive ใน CI**: EAS จะขึ้นว่า "Distribution Certificate is not validated for non-interactive builds" แล้วก็เซ็นต่อไปอยู่ดี

**ใน CI นั้น EAS ไม่ได้ตรวจตัวใบรับรองซ้ำ การเพิกถอนจึงอาจไปโผล่ตอนส่งเท่านั้น** วิธีแก้: รัน build แบบ interactive ที่ล็อกอินบัญชี Apple ไว้ หรือใช้ `eas credentials --platform ios` เข้าเมนู Build Credentials แล้วเลือก "Distribution Certificate: Add a new one to your account" โปรไฟล์ที่มีใบรับรองเก่าจะใช้ไม่ได้ EAS จะตรวจและสร้างใหม่ให้ใน build ถัดไป ข้อจำกัดของ Apple เรื่องจำนวนใบรับรองอธิบายไว้ใน[คู่มือเรื่องใบรับรองนักพัฒนา iOS](https://devoria.fr/th/blog/ios-certificate-provisioning-profile-expo)

### ไบนารีถูกแก้หลังจากเซ็น

ลายเซ็นจะผนึกโค้ด ทรัพยากร และ metadata ไว้ด้วยค่า hash ตามที่ [technote TN3126 ของ Apple](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes) อธิบาย การแตกไฟล์ IPA เพื่อแก้ไฟล์แล้วบีบอัดกลับจะทำให้ผนึกนี้เสีย **ให้แก้ใน config ของคุณ แล้ว build ใหม่** อย่าไปแก้ IPA ที่ EAS สร้างให้เด็ดขาด

ตรรกะเดียวกันใช้กับโค้ดที่วางไว้ผิดที่ เช่นอยู่ในไฟล์ `.zip`: App Store เซ็นมันใหม่ไม่ได้ Apple อธิบายตำแหน่งที่อนุญาตไว้ในหน้า[การวางเนื้อหาใน bundle](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle)

### ข้อมูลรับรองแบบ local

ถ้าโปรไฟล์ EAS ของคุณใช้ `"credentialsSource": "local"` ไฟล์ `credentials.json` จะชี้ไปที่ใบรับรอง `.p12` และโปรไฟล์ `.mobileprovision` ให้ตรวจโปรไฟล์ด้วยคำสั่งในขั้นที่ 3: มันต้องเป็นประเภท App Store และมีใบรับรอง distribution ตัวปัจจุบันของคุณอยู่ และอย่าเก็บไฟล์พวกนี้ไว้ใน repo เช่นเดียวกับ [API key ของแอป Expo](https://devoria.fr/th/blog/secret-api-key-expo-app)

### เมื่อทุกอย่างถูกต้องหมด

ยังมีอีกกรณีที่น่าหงุดหงิด บนฟอรัมของ Apple มีนักพัฒนาที่ error หายไปเองเมื่อส่ง build เดิมซ้ำโดยไม่ได้แก้อะไรเลย ในเดือนสิงหาคมและกันยายน 2026 มีสองกระทู้ที่เจอกลับกัน: ใบรับรองและโปรไฟล์ใหม่ ลายเซ็นตรวจแล้ว แต่ยังล้มเหมือนเดิม ในกระทู้หนึ่ง วิศวกรของ Apple แนะนำให้ส่งรายงานบั๊กพร้อม IPA ผลวิเคราะห์ลายเซ็น และ log ของ Transporter แล้วติดต่อ App Store Connect

ดังนั้นให้ส่งใหม่หนึ่งครั้งพร้อมเลข build ใหม่ ถ้า error ยังกลับมาทั้งที่ 4 คำสั่งของคุณผ่านหมด ให้แจ้ง Apple พร้อมข้อมูลเหล่านี้ **อย่าเพิกถอนใบรับรองเพราะความเคยชิน** มันไม่ได้แก้อะไรเพิ่ม แถมทำให้โปรไฟล์ของคุณใช้ไม่ได้

## ส่ง build โดยไม่เจอเรื่องไม่คาดฝัน

ลายเซ็นตรวจได้ในสองนาทีก่อนส่ง การตรวจอัตโนมัติอื่นๆ ก็ต้องรอบคอบแบบเดียวกัน เช่น [ITMS-90725](https://devoria.fr/th/blog/itms-90725-sdk-version-issue-expo) เรื่องเวอร์ชัน Xcode หรือ [ITMS-90683](https://devoria.fr/th/blog/itms-90683-missing-purpose-string-expo) เรื่องข้อความขอสิทธิ์ ขั้นตอนครบตั้งแต่ build จนถึงส่งโดยไม่ต้องมี Mac อยู่ใน[เผยแพร่แอป iOS โดยไม่มี Mac](https://devoria.fr/th/blog/publish-ios-app-without-mac-expo-eas)

การถูก reviewer ปฏิเสธต้องใช้มุมมองที่กว้างกว่านี้ วิธีรับมืออยู่ในหน้า[แอปถูก Apple ปฏิเสธ](https://devoria.fr/th/expertise/app-rejected-by-apple) และเหตุผลที่เจอบ่อยที่สุดอยู่ใน[ทำไม Apple ปฏิเสธแอป](https://devoria.fr/th/blog/apple-app-rejection-reasons-real-cases)

ถ้าอยากตรวจความพร้อมก่อนส่ง [Review Kit](https://devoria.fr/th/kits/app-review) รวม checklist ของผมกับ skill ของ Claude Code ที่ช่วยอ่านทวนโปรเจกต์ของคุณ ถ้าการส่งติดขัดและอยากให้คนช่วยดู [จองเวลาหนึ่งชั่วโมงกับผม](https://devoria.fr/th/coaching) เราจะดูโปรเจกต์ของคุณผ่านวิดีโอคอลบนหน้าจอของคุณเลย และถ้าคุณกำลังเตรียมปล่อยแอปแรก [ทำแบบประเมินฟรี](https://devoria.fr/th/diagnostic) มันจะเรียงขั้นตอนให้เป็นลำดับ และส่ง checklist กันโดน Apple ปฏิเสธของผมให้คุณ

## คำถามที่พบบ่อย

### ITMS-90034 คือการถูก App Review ปฏิเสธหรือเปล่า?

ไม่ใช่ครับ มันคือการตรวจอัตโนมัติตอนส่ง build ก่อน TestFlight และก่อนการรีวิวใดๆ ไม่มีใครเปิดแอปของคุณ Apple แค่พบว่าลายเซ็นของมันไม่ได้มาจากใบรับรอง distribution ที่ใช้ได้

### ต้องเพิกถอนใบรับรอง distribution เพื่อแก้ ITMS-90034 ไหม?

เฉพาะเมื่อใบรับรองรั่วไหลหรือใช้ไม่ได้อยู่แล้วเท่านั้น การเพิกถอนใบรับรองที่ยังใช้ได้จะทำให้โปรไฟล์ใช้ไม่ได้โดยไม่ได้แก้ต้นเหตุ เริ่มจากอ่านลายเซ็นของ IPA ด้วย `codesign` แล้วแก้ตามที่แผนผังการตัดสินใจชี้

### แก้ ITMS-90034 ด้วยการอัปเดตแบบ OTA ได้ไหม?

ไม่ได้ครับ ลายเซ็นเป็นส่วนหนึ่งของไบนารี และ build ที่ถูกปฏิเสธจะใช้ไม่ได้ตลอดไป คุณต้องสร้างไบนารีใหม่ที่เซ็นถูกต้องแล้วส่งใหม่

### ทำไม error ถึงพูดถึง widget ไม่ใช่ตัวแอป?

เพราะ widget เป็น bundle แยก เซ็นด้วยโปรไฟล์ของตัวเอง ถ้ามันไม่ได้ประกาศให้ EAS รู้ หรือถูกเซ็นด้วยวิธีอื่น มันจะทำให้การส่งทั้งหมดล้ม ให้ประกาศ extension ไว้ใน config แล้ว build ใหม่

### ถ้า codesign บอกว่าทุกอย่างถูกต้องแล้วต้องทำอย่างไร?

ตรวจโปรไฟล์ที่ฝังอยู่และ extension ทุกตัวด้วย ถ้าทุกอย่างเรียบร้อย ให้ส่งใหม่หนึ่งครั้งพร้อมเลข build ใหม่ ถ้า error ยังอยู่ ให้ส่งรายงานถึง Apple พร้อม IPA ผลลัพธ์ของ `codesign` และ log การส่ง


## โปรเจกต์ของคุณ

[Review Kit](https://devoria.fr/th/kits/app-review): เช็กลิสต์รีวิว App Store ของผม การถูก Apple ปฏิเสธที่ผมแก้ไขแล้ว เช็กลิสต์ของ Google Play และ skill ของ Claude Code อีกสามตัว ฿1,849

[iOS & Android Kit](https://devoria.fr/th/kits/ios): สร้างแอป iPhone และ Android ของคุณด้วย Claude Code: โค้ดเริ่มต้นจากแอปของผม เส้นทางจนถึงสโตร์ และชุดคิททั้งหมด ฿3,699

[แบบประเมิน: อะไรกั้นคุณไว้จากแอป iPhone ของคุณ](https://devoria.fr/th/diagnostic): 7 คำถาม 60 วินาที: รู้ว่าอะไรที่ขวางคุณจากการเผยแพร่แอป iPhone จริง ๆ พร้อมเส้นทาง 4 ขั้นตอนและชุดคิทที่เหมาะกับคุณ
