eas submit iOS error: สาเหตุและวิธีแก้ที่พบบ่อย
โดย Mehdi Azizi
เผยแพร่เมื่อ , 10 นาที
eas submit ล้มเหลว? ข้อความจริงจาก EAS และ App Store Connect พร้อมสาเหตุและวิธีแก้: ascAppId, คีย์ API, สัญญา Apple และโค้ด ITMS
เวลา eas submit --platform ios ล้มเหลว ข้อความ error แทบทุกครั้งจะบอกว่าควรดูตรงไหน ไม่การตั้งค่า EAS ของคุณยังไม่ครบ ก็บัญชี Apple ของคุณติดอะไรบางอย่าง หรือไม่ Apple ก็ปฏิเสธไฟล์ไบนารี สองกรณีแรกแก้ได้ในไม่กี่นาที ไม่ต้อง build ใหม่ กรณีที่สามดูออกได้จากโค้ด ITMS และแทบทุกครั้งต้อง build ใหม่
ผมเผยแพร่แอป iOS ของผม รวมถึง Solys, TradaZen และ Nolera ด้วย Expo และ EAS ข้อความที่ยกมาในบทความนี้คัดลอกมาจากซอร์สโค้ดของ EAS CLI บนรีโพ GitHub ทางการของ Expo ซึ่งผมอ่านทวนล่าสุดเมื่อ 3 พฤศจิกายน 2026 ฟอรัมเก่าของ Expo ตอนนี้ส่งต่อไปที่ Discord แล้ว ตัวโค้ดจึงยังเป็นแหล่งที่เชื่อถือได้ที่สุด ถ้าอยากดูขั้นตอนทั้งหมด ตั้งแต่ไฟล์ eas.json ไปจนถึงการส่งรีวิว ให้อ่าน EAS Submit iOS: เผยแพร่แอป Expo บน App Store ก่อน ส่วนบทความนี้เราจะมาซ่อมกัน
eas submit ทำอะไร และต้องใช้อะไรบ้าง
ตามเอกสารของ Expo คำสั่งนี้จะส่งไฟล์ .ipa ของคุณไปยัง App Store Connect build จะขึ้นใน TestFlight หลังจาก Apple ประมวลผลเสร็จ ปกติใช้เวลา 10 ถึง 15 นาที คำสั่งนี้ไม่ได้ส่งแอปของคุณเข้ารีวิว ขั้นตอนนั้นคุณยังต้องทำเองใน App Store Connect
หน้าของ Expo เรื่องการส่ง iOS ระบุสิ่งที่ต้องมีไว้สามอย่าง:
- บัญชี Apple Developer แบบเสียเงิน ซึ่งจำเป็นสำหรับการส่งทุกครั้งไปยัง App Store
- bundle identifier ใน
ios.bundleIdentifier - ติดตั้ง EAS CLI และล็อกอินบัญชี Expo ของคุณแล้ว
ถ้าจะส่งแบบไม่ต้องโต้ตอบ หน้าเดียวกันนี้เพิ่มการตั้งค่าอีกสองอย่าง:
ascAppIdในโปรไฟล์submitของeas.jsonคือหมายเลขของหน้าแอปคุณใน App Store Connect- คีย์ API ของ App Store Connect ให้ EAS จัดการให้ หรือคุณเตรียมเอง วิธีสร้าง บทบาท และการเพิกถอนคีย์ อธิบายไว้ละเอียดใน คีย์ API ของ App Store Connect (.p8)
โปรไฟล์ขั้นต่ำมีแค่ไม่กี่บรรทัด ค่าที่ใส่ไว้เป็นค่าสมมติ:
{
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890"
}
}
}
}
ถ้า EAS เก็บคีย์ API ของคุณไว้แล้ว โปรไฟล์นี้ก็พอ แอปส่วนใหญ่ของผมเป็นแบบนี้
อ่านข้อความ error: สามกลุ่มหลัก
ก่อนหาวิธีแก้ ให้ดูก่อนว่าคำสั่งหยุดตรงจังหวะไหน ตารางนี้คือเกณฑ์ที่ผมใช้ทุกครั้งที่ส่งไม่ผ่าน
| จังหวะที่ล้มเหลว | กลุ่ม | ต้อง build ใหม่ไหม |
|---|---|---|
| ก่อนส่งอะไรออกไป | การตั้งค่า EAS | ไม่ |
| ตอนเชื่อมต่อกับ Apple หรือสร้างหน้าแอป | บัญชี Apple | ไม่ |
| หลังส่งแล้ว เจอโค้ด ITMS-90xxx | ไบนารีถูกปฏิเสธ | แทบทุกครั้ง |
รายละเอียดดูได้ในหน้าของการส่งครั้งนั้นบนแดชบอร์ดของ Expo Expo แนะนำให้อ่าน log ในหน้านั้น และมองหากล่อง “Build Annotations” ซึ่งจะชี้สาเหตุที่ล้มเหลวบ่อย ๆ ส่วนในเทอร์มินัล ออปชัน --verbose จะแสดง log ของ EAS Submit เสมอ ตามเอกสารอ้างอิงของ EAS CLI
Error จากการตั้งค่า EAS
“Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode.”
คุณรันคำสั่งด้วย --non-interactive เช่นใน CI และโปรไฟล์ของคุณไม่มี ascAppId โค้ดของ EAS CLI จึงหยุดทำงาน เพราะมันถามคุณไม่ได้ และสร้างหน้าแอปแทนคุณก็ไม่ได้
วิธีแก้: คัดลอกหมายเลขหน้าแอปของคุณมาใส่ใน ascAppId Expo บอกไว้ว่าหาได้ที่ไหน: ใน App Store Connect เปิดแอปของคุณ แล้วไปที่ App Information คือช่อง Apple ID ใต้ General Information เป็นตัวเลขราวสิบหลัก ไม่ใช่อีเมล Apple ของคุณ และไม่ใช่ bundle identifier
ตอนทำ Nolera ถ้าไม่มี ascAppId คำสั่งจะขอ session ของ Apple Developer ซึ่งหมดอายุได้ ตั้งแต่ใส่หมายเลขนี้ไว้ใน eas.json การส่งก็ไม่ถามอะไรอีกเลย
ใส่
ascAppIdก่อน build ไม่ใช่หลัง build จนถึง SDK 57 fingerprint ที่ Expo คำนวณ จะรวมeas.jsonเข้าไปด้วยเสมอ ในแอป Vigie ซึ่ง runtime version ใช้นโยบายfingerprintการเพิ่มหมายเลขนี้หลัง build ทำให้ fingerprint เปลี่ยน อัปเดตที่ปล่อยตามมาจะไม่มีวันไปถึง build ที่ติดตั้งอยู่ ตั้งแต่ SDK 58 พรีเซ็ตค่าเริ่มต้นของ fingerprint คือbalancedซึ่งไม่สนใจeas.jsonตามบันทึกการเปลี่ยนแปลงของ Expo
“App Store Connect API Keys cannot be set up in --non-interactive mode.”
โปรไฟล์ของคุณไม่มีคีย์ และ EAS ก็ไม่มีคีย์ที่ผูกกับแอปของคุณเลย Expo ระบุไว้ว่า ในโหมดไม่โต้ตอบ คำสั่งจะขอคีย์จากคุณไม่ได้ และจะล้มเหลวพร้อมข้อความนี้
แก้ได้สองทาง:
- ให้ EAS สร้างและเก็บคีย์ให้ รัน
eas credentials --platform iosหนึ่งครั้งในโหมดโต้ตอบบนเครื่องของคุณ แล้วให้มันตั้งค่าคีย์ API ของ App Store Connect สำหรับแอปของคุณ - ใช้คีย์ของคุณเอง ใส่ใน
ascApiKeyPath,ascApiKeyIssuerIdและascApiKeyIdตามเอกสารอ้างอิงของ eas.json ทั้งสามช่องรับ environment variable ได้ เช่น$ASC_API_KEY_PATH
ในแอปล่าสุดของผม ออปชัน --auto-submit ต้องการ Apple ID เพื่อสร้างคีย์สำหรับส่ง ผมเลยใส่สามช่องของคีย์ตัวเองในโปรไฟล์บนสำเนางานในเครื่อง ซึ่งไม่เคย commit จากนั้นก็ส่ง build ที่เสร็จแล้วด้วย --id และ --non-interactive
“EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter.”
ตัวแปรนี้มีค่าที่ไม่ใช่รหัสผ่านเฉพาะแอป ส่วนใหญ่มักเป็นรหัสผ่าน Apple ของคุณเอง EAS CLI ตรวจรูปแบบนี้ก่อนส่งทุกครั้ง
ตามหน้าช่วยเหลือของ Apple รหัสผ่านเฉพาะแอปสร้างได้ที่ account.apple.com ในหัวข้อ App-Specific Passwords โดยต้องเปิดการยืนยันตัวตนสองขั้นตอนไว้ และจะถูกเพิกถอนทันทีที่คุณเปลี่ยนรหัสผ่านบัญชี Apple Expo มองว่าวิธีนี้ปลอดภัยน้อยกว่าคีย์ API ซึ่งเป็นวิธีเริ่มต้นที่ Expo แนะนำ
Error จากบัญชี Apple
“… agree to the latest Program License Agreement in your developer account.”
ข้อความเต็มขึ้นต้นด้วย “You currently don't have access to this membership resource” ฝั่ง Apple คำตอบดิบอาจมี “Unable to process request - PLA Update available” ส่วนขั้นตอนการส่งรุ่นใหม่ของ EAS มักแสดง “A required Apple agreement is missing or has expired” แทน
สาเหตุเหมือนกัน: Apple อัปเดตสัญญา และยังไม่มีใครกดยอมรับ มีแค่เจ้าของบัญชี หรือ Account Holder เท่านั้นที่ยอมรับสัญญาได้ ตามตารางบทบาทของ Apple โค้ดของ EAS บอกให้เขาไปที่หน้า Business ใน App Store Connect แล้วถ้า Apple เสนอ ก็ไปที่บัญชีของเขาบน developer.apple.com ด้วย จากนั้นรันคำสั่งใหม่ สัญญาสำหรับแอปเสียเงินมีคู่มือแยกไว้: Paid Apps Agreement ใน App Store Connect
“App Store Connect rejected the API authentication credentials.”
Apple ตอบกลับด้วย error 401 คือ NOT_AUTHORIZED EAS ระบุสาเหตุไว้สามข้อ: คีย์ไม่ active แล้ว คีย์มาจากบัญชี App Store Connect อื่น หรือ Key ID เนื้อหาคีย์ หรือ Issuer ID ผิด
ตรวจตัวระบุทั้งสองใน App Store Connect เมนู Users and Access แท็บ Integrations ตามข้อมูลของ Apple Issuer ID แสดงอยู่ด้านบนของหน้า และ Key ID อยู่ในรายการคีย์ที่ active คีย์ที่ถูกเพิกถอนแล้วเปิดใช้ใหม่ไม่ได้อีกเลย Apple แสดงคีย์นั้นไว้ใต้ Revoked เป็นเวลา 30 วัน คุณต้องสร้างคีย์ใหม่
“App Store Connect app for application identifier … was not found.”
หาหน้าแอปที่ ascAppId ชี้ไปไม่เจอด้วยคีย์ของคุณ EAS ขอให้คุณตรวจหมายเลขนี้ และตรวจว่าคีย์เข้าถึงแอปนั้นในบัญชีที่ถูกต้องได้จริง มันยังแสดงรายชื่อแอปบางตัวที่คีย์นี้มองเห็นให้ด้วย ถ้าใช้เครื่องมือส่งของ Apple ปัญหาเดียวกันนี้จะแสดงเป็น “No suitable application records were found”
สาเหตุที่เจอบ่อยมีสามข้อ สองข้อในนั้นมาจากกระทู้นี้ในฟอรัมของ Apple:
- ยังไม่มีหน้าแอป สร้างใน App Store Connect หรือเอา
ascAppIdออกเพื่อให้คำสั่งสร้างให้ - หมายเลขมาจากบัญชีอื่น คุณคัดลอก
ascAppIdมาจากทีมอื่น หรือจากโปรเจกต์อื่น - ผู้ใช้ไม่มีสิทธิ์เข้าถึงแอป App Manager หรือ Developer อาจถูกจำกัดให้เข้าถึงได้เฉพาะบางแอป ส่วนคีย์ระดับทีมเข้าถึงได้ทุกแอปในบัญชี
“… is not available to team” หรือ “… is not available to provider”
ข้อความนี้ขึ้นตอนที่ EAS สร้างหน้าแอปแทนคุณ เพราะไม่มี ascAppId bundle identifier ถูกทีมอื่นใช้ไปแล้ว EAS ขอให้คุณเปลี่ยนค่านี้ในการตั้งค่าแอป แล้วรันใหม่
“App name "…" is already taken. Using generated name "…"”
อันนี้ไม่ใช่การล้มเหลว เมื่อชื่อถูกใช้ไปแล้วบน App Store, EAS จะเติมตัวอักษรสุ่มหกตัวแล้วลองใหม่ สูงสุดห้าครั้ง คุณค่อยเปลี่ยนชื่อหน้าแอปทีหลังใน App Store Connect ได้ ถ้าไม่อยากเจอ ให้ใส่ appName และ language ในโปรไฟล์ก่อนส่งครั้งแรก ถ้าไม่มี language ภาษาหลักจะเป็น en-US
Error จากไบนารี: โค้ด ITMS
หลังส่ง Apple จะประมวลผล build ถ้าปฏิเสธ log จะแสดงโค้ด ITMS หนึ่งตัวหรือมากกว่า นี่คือโค้ดที่ขั้นตอนการส่งของ EAS รู้จักและแปลความหมายให้:
| โค้ด ITMS | สิ่งที่ Apple ปฏิเสธ | วิธีแก้ |
|---|---|---|
| 90189 | หมายเลข build ซ้ำ | autoIncrement |
| 90062, 90186, 90478 | เวอร์ชันถูกปิดแล้วหรือเก่ากว่าที่มีอยู่ | เพิ่ม version |
| 90683 | ไม่มีข้อความขออนุญาต (purpose string) | ios.infoPlist |
| 90725 | iOS SDK เก่าเกินไป | อิมเมจ iOS หรือ Expo SDK |
| 90054, 90055 | bundle ไม่ตรงกับหน้าแอปที่ชี้ไป | แก้ ascAppId |
| 90022, 90023, 90391, 90713 | ไอคอนหายหรือประกาศไม่ถูกต้อง | ตรวจไอคอนใหม่ |
| 90771 | ไม่มีตัวระบุงานเบื้องหลัง | ios.infoPlist |
ข้อสังเกตสามข้อจากข้อความเหล่านี้:
- หมายเลข build ต้องไม่ซ้ำในแต่ละเวอร์ชัน สำหรับ 90189, EAS แนะนำให้ใส่
"autoIncrement": trueในeas.jsonรายละเอียดทั้งหมดอยู่ใน หมายเลข build และเวอร์ชัน - สำหรับ 90725 EAS แนะนำให้เลือกอิมเมจ iOS ที่ใหม่กว่าใน
eas.jsonและถ้าจำเป็นก็อัปเป็น Expo SDK ที่ยังรองรับอยู่ - สำหรับ 90771 Info.plist ของคุณประกาศโหมดเบื้องหลัง
processingแต่ไม่มีคีย์BGTaskSchedulerPermittedIdentifiers
ยกเว้น 90054 และ 90055 ที่แค่ชี้ไปยังหน้าแอปที่ถูกต้องหรือ build อื่น การแก้จะเกี่ยวกับตัวไบนารี: build ใหม่ แล้วส่งอีกครั้ง มีสองโค้ดที่มีคู่มือแยก: ITMS-90683 กับ Expo และ ITMS-90725
ปลายเดือนกันยายน 2026 build หนึ่งของ Solys ถูกปฏิเสธตอนส่งเพราะ ITMS-90683 ผมลบข้อความขออนุญาตเรื่องรูปภาพออกไประหว่างเก็บกวาดไฟล์ config Solys ไม่ได้ใช้รูปภาพ แต่มีไลบรารีตัวหนึ่งในโปรเจกต์ที่เรียก Photos API ของ iOS Apple วิเคราะห์ไบนารี ไม่ได้ดูการใช้งานจริง ตั้งแต่นั้นผมไม่ลบข้อความพวกนี้อีกเลย
ส่วนสถานะ Missing Compliance ไม่ใช่ error ตอนส่ง แต่หมายถึงคุณยังไม่ได้ประกาศเรื่องการเข้ารหัส ซึ่งอธิบายไว้ในคู่มือการเผยแพร่ด้วย EAS
เช็กลิสต์ของผมก่อนส่งทุกครั้ง
ascAppIdอยู่ในโปรไฟล์submitและใส่ไว้ก่อน build- คีย์ API ให้ EAS จัดการ หรือสามช่องของคีย์ชี้ไปที่ไฟล์
.p8ที่เก็บไว้นอกรีโพ - Account Holder ยอมรับสัญญาล่าสุดใน App Store Connect แล้ว
- เปิด
autoIncrementไว้ พร้อม"appVersionSource": "remote"ซึ่งExpo แนะนำตั้งแต่ EAS CLI 12 versionสูงกว่าเวอร์ชันล่าสุดที่ได้รับอนุมัติ- API ที่อ่อนไหวทุกตัวที่อยู่ในไบนารีมีข้อความขออนุญาตของตัวเอง
- สำหรับแอปใหม่ ใส่
appNameและlanguageไว้ก่อนส่งครั้งแรก
ส่งแอปแรกของคุณโดยไม่ติดค้าง
คำสั่งนี้เป็นแค่ขั้นตอนเดียว iOS & Android Kit เริ่มจากโค้ดตั้งต้นของแอปผม รวมระบบสมัครสมาชิกด้วย และพาคุณผ่านสี่ขั้นตอนไปจนถึง App Store ตามจังหวะของคุณเอง
ถ้าคุณกำลังเตรียมปล่อยแอปแรก ทำแบบประเมินฟรี แล้วคุณจะรู้ว่าอะไรที่ขวางคุณอยู่จริง ๆ และจะได้รับเช็กลิสต์กันโดน Apple ปฏิเสธของผม ส่วนเรื่องหน้าแอป ภาพหน้าจอ และการผ่านรีวิว หน้า เผยแพร่แอปบน App Store อธิบายไว้ทุกขั้นตอน
คำถามที่พบบ่อย
ทำไม eas submit ถึงล้มเหลวเฉพาะตอนรันใน CI?
ในโหมด --non-interactive คำสั่งถามอะไรคุณไม่ได้เลย มันต้องมี ascAppId ในโปรไฟล์ และคีย์ API ที่ผูกกับแอปไว้แล้ว หรือมีสามช่องของคีย์ใน eas.json ถ้ารันบนเครื่องคุณ มันจะถามคำถามเหล่านี้กับคุณเอง
ต้อง build ใหม่หลังเจอ error จาก eas submit ไหม?
เฉพาะเมื่อ Apple ปฏิเสธไบนารีพร้อมโค้ด ITMS ข้อยกเว้นคือ ITMS-90054 และ 90055 ซึ่ง build ชี้ไปผิดหน้าแอป แค่ส่งใหม่ไปยังหน้าที่ถูกต้องก็พอ error จากการตั้งค่าและบัญชีแก้ได้ใน eas.json, ใน App Store Connect หรือในบัญชี Apple ของคุณ แล้วส่ง build เดิมอีกครั้ง เช่น ใช้ --latest หรือ --id
ดู log ของการส่งด้วย EAS Submit ได้ที่ไหน?
ในหน้าของการส่งครั้งนั้นบนแดชบอร์ดของ Expo ซึ่ง Expo แนะนำให้อ่าน log และกล่อง “Build Annotations” ในเทอร์มินัล ให้เพิ่ม --verbose เพื่อแสดง log เสมอ
ใช้ eas submit กับบัญชี Apple ฟรีได้ไหม?
ไม่ได้ Expo กำหนดให้ใช้บัญชี Apple Developer แบบเสียเงินเพื่อส่งแอปไปยัง App Store บัญชีฟรีใช้ทดสอบบน iPhone ของคุณเองได้ แต่ใช้ App Store Connect ไม่ได้
ควรให้คีย์ API มีบทบาทอะไรสำหรับ eas submit?
คู่มือของ Expo ให้คีย์มีบทบาท Admin ตามตารางบทบาทของ Apple การส่ง build ยังทำได้ด้วยบทบาท App Manager และ Developer build Expo ของผมใช้คีย์ระดับทีมที่มีบทบาท App Manager มีแค่ Account Holder และ Admin เท่านั้นที่สร้างคีย์ระดับทีมได้
“Increment Build Number” ใน EAS หมายความว่าอะไร?
Apple ปฏิเสธ build ด้วยโค้ด ITMS-90189 คือหมายเลข build นี้มีอยู่แล้วสำหรับเวอร์ชันนี้ ให้เปิด "autoIncrement": true ใน eas.json หรือเพิ่มค่า ios.buildNumber แล้ว build ใหม่

