ITMS-90034 錯誤修正:簽署遺失或無效
作者:Mehdi Azizi
發布於 ,8 分鐘
ITMS-90034 代表你的 build 沒有用有效的發佈憑證簽署。先用 codesign 檢查簽署,再用 EAS 重新產生 store build。
ITMS-90034 會在你把 build 上傳到 App Store Connect 時出現。它的意思是:你的 app,或其中某個元件,沒有用 Apple 的提交憑證簽署,也就是沒有用有效的發佈憑證(distribution certificate)簽署。修正方法:找出哪個 bundle 簽錯了、為什麼簽錯,然後重新產生一個為 App Store 簽署的 build。
這篇指南只專注在這個錯誤。如果你對憑證和描述檔還不太熟,先看iOS 開發者憑證與 provisioning profile。在這裡,你會看到該怎麼讀錯誤訊息、一張決策表、檢查 IPA 的指令,以及用 EAS 管理的憑證來修正的方法。EAS 的部分,我讀過 EAS CLI 24.10.0 中挑選憑證的程式碼。
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)」。
「提交憑證」指的就是發佈憑證。Apple 關於憑證的說明寫得很清楚:開發憑證用來在你自己的裝置上執行 app,發佈憑證則用來發佈 app,或上傳到 App Store Connect。
看清楚訊息裡的路徑:它指出的就是出問題的 bundle。 Payload/MyApp.app 指的是 app 本身。以 .appex 結尾的路徑指的是擴充功能,例如 widget。以 .framework 結尾的路徑指的是內嵌的函式庫。
這不是審查人員的拒絕。驗證是在上傳時或 build 處理期間失敗的,發生在 TestFlight 之前:這個 build 永遠到不了你的測試人員手上。
決策表:從錯誤訊息到修正
每一列對應一個線索,你會在錯誤訊息、下一節的指令或 EAS 的日誌中看到。請依序比對:第一個符合的就是你的方向。
| 你看到的現象 | 可能原因 | 修正方式 |
|---|---|---|
路徑以 .appex 結尾 | 擴充功能簽署錯誤 | 宣告擴充功能 |
Signature=adhoc | build 未簽署 | 用 store 設定檔 build |
Apple Development | 開發用 build | 用 store 設定檔 build |
讀得到 ProvisionedDevices | 內部 build(ad hoc) | 用 store 設定檔 build |
sealed resource | IPA 事後被修改 | 重新 build |
| EAS:「no longer valid」 | 憑證已撤銷 | 建立新憑證 |
| 全部都有效 | Apple 端的問題 | 重新上傳,再回報 |
用四個指令檢查你的 IPA
從 expo.dev 上的 build 頁面下載 IPA,然後在 Mac 上開啟終端機。
1. 是誰簽署了這個 app?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
codesign 會輸出到標準錯誤,所以要加 2>&1。根據 Apple 的技術說明 TN3161,每一行 Authority 都是信任鏈中的一環。第一行必須以 Apple Distribution: 或 iPhone Distribution: 開頭,後面接你的團隊名稱。後者是舊的 iOS Distribution 類型的名稱:從程式碼來看,EAS CLI 24.10.0 仍然會建立這種類型的憑證。如果你看到 Apple Development:,那就是開發用 build。如果你看到 Signature=adhoc,而且完全沒有 Authority 行,代表這個二進位檔沒有用任何憑證簽署。
2. app 在簽署後有被修改過嗎?
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. 內嵌的是哪個描述檔?
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profile.plist
plutil -extract ProvisionedDevices xml1 -o - profile.plist
plutil -extract ExpirationDate raw profile.plist
這些是關於描述檔的技術說明 TN3125裡的指令。App Store 描述檔不包含任何裝置清單:第二行應該回應 Could not extract value。如果它顯示了裝置識別碼,那就是 ad hoc 描述檔,也就是內部 build 用的那種。第三行會顯示描述檔的到期日。
4. 擴充功能和 framework 的簽署是否一致?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
每個元件顯示的 Authority 行都應該和 app 相同。如果某個元件不一樣,錯誤訊息指的就是它。
如果你想在上傳前先檢查,TN3161 建議使用 altool,它和 Xcode 的 Validate App 按鈕做的是同樣的檢查。它需要一把 App Store Connect API 金鑰,金鑰檔 AuthKey_<KEY_ID>.p8 要放在 ~/.appstoreconnect/private_keys:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
用 EAS 修正,依原因逐一處理
把內部或開發用 build 送給 Apple
根據 Expo 關於 eas.json 的文件,"distribution": "internal" 的 build 不是為商店簽署的:它們用的是 ad hoc 描述檔。只有 distribution 為 store(預設值)的設定檔,才會產生可以上傳的 build。最保險的做法是直接上傳你剛 build 好的版本,不要手動挑選:
eas build --platform ios --profile production --auto-submit
如果你用 eas submit --path,要確認檔案真的是你最新的 store build。在 Apple 論壇上,有個團隊發現他們的上傳工具每次送出的都是一個舊的 IPA,而那個 IPA 被版本控制在 git 裡。
漏掉的擴充功能
每個擴充功能都是獨立的 bundle,有自己的識別碼和自己的描述檔。在使用原生程式碼產生(prebuild)的 Expo 專案中,Expo 關於 iOS 擴充功能的頁面要求你在 extra.eas.build.experimental.ios.appExtensions 裡宣告它們。這樣 EAS CLI 在 build 之前就知道它們的存在,並會建立或驗證它們的憑證。大多數會加入擴充功能的函式庫,都會透過自己的 plugin 幫你寫好這段宣告。
Solys 是我做的小遊戲鬧鐘,內含四個擴充功能:一個 widget 和三個 Screen Time 擴充功能。這四個都宣告在它的設定裡,EAS 也為每一個準備了描述檔。在 Xcode 裡手動加入、卻沒有這段宣告的擴充功能,最有可能就是錯誤訊息裡那個 .appex 路徑的元凶。
憑證已撤銷或過期
Apple 關於憑證的頁面講得很明白:用已過期或已撤銷的憑證簽署的 build,你就不能再上傳了。一個已經上傳、但還沒送審的 build,如果它的憑證被撤銷,甚至可能變成 Invalid Binary。
EAS CLI 24.10.0 的程式碼顯示了這種情況什麼時候會被忽略:
- 互動式 build,已登入 Apple:EAS 會把它的憑證和 Apple 那邊仍有效的憑證比對。如果找不到,會顯示「Current distribution certificate is no longer valid in Apple Dev Portal」,並讓你選擇或建立一個新的。
- 互動式 build,未登入:EAS 只檢查日期,並提醒你它跳過了 Apple 端的驗證。
- 非互動式 build,在持續整合(CI)中:EAS 顯示「Distribution Certificate is not validated for non-interactive builds」,然後照樣簽署。
在持續整合中,EAS 不會重新檢查憑證本身:撤銷的問題可能要到上傳時才會發現。 修正方式:登入你的 Apple 帳號,執行一次互動式 build,或者使用 eas credentials --platform ios,進入 Build Credentials 選單,再選「Distribution Certificate: Add a new one to your account」。包含舊憑證的描述檔會失效:EAS 會在下一次 build 時檢查並重新產生它們。Apple 對憑證數量的限制,詳見iOS 開發者憑證指南。
簽署後被修改的二進位檔
簽署會用雜湊值把程式碼、資源和中繼資料封存起來,Apple 的技術說明 TN3126 有詳細解釋。把 IPA 解壓縮、改一個檔案、再重新壓縮,就會破壞這個封存。請在你的設定裡修改,然後重新 build。 絕對不要修改 EAS 產生的 IPA。
程式碼放錯位置也是同樣的道理,例如放在 .zip 壓縮檔裡:App Store 無法重新簽署它。Apple 在bundle 內容的頁面中說明了允許的位置。
本機憑證
如果你的 EAS 設定檔使用 "credentialsSource": "local",你的 credentials.json 會指向一個 .p12 憑證和一個 .mobileprovision 描述檔。用步驟 3 的指令檢查這個描述檔:它必須是 App Store 類型,並且包含你目前的發佈憑證。另外,這些檔案要放在儲存庫之外,就像Expo app 的 API 金鑰一樣。
全部都有效的時候
還有一種讓人很挫折的情況。在 Apple 論壇上,有開發者把同一個 build 重新上傳,什麼都沒改,錯誤就消失了。2026 年 8 月和 9 月,有兩篇討論串描述了相反的情況:全新的憑證和描述檔、簽署也驗證過,卻還是一直失敗。其中一篇裡,一位 Apple 工程師建議提交錯誤回報,附上 IPA、簽署分析和 Transporter 的日誌,然後聯絡 App Store Connect。
所以,先用新的 build 號碼重新上傳一次。如果你的四個指令結果都沒問題,錯誤卻又出現,就帶著這些資料回報給 Apple。不要反射性地撤銷你的憑證:這不會多解決什麼,反而會讓你的描述檔失效。
上傳 build,不再有意外
上傳前花兩分鐘就能檢查簽署。其他自動檢查也需要同樣的嚴謹,例如 Xcode 版本相關的 ITMS-90725,或權限說明文字相關的 ITMS-90683。從 build 到上傳、不用 Mac 的完整流程,請看沒有 Mac 也能發佈 iOS app。
審查人員的拒絕就需要多一點思考:處理步驟在app 被 Apple 拒絕這一頁,最常見的拒絕原因則在Apple 為什麼拒絕你的 app。
如果你想在上傳前檢查你的資料,Review Kit 收錄了我的檢查清單,以及會幫你審閱專案的 Claude Code skills。如果你的上傳卡住了,想找真人幫忙看看,跟我預約一小時:我們透過視訊,在你的螢幕上一起檢查你的專案。如果你正在準備第一次上架,做一下免費診斷:它會幫你把步驟排好順序,並寄給你我的防 Apple 拒絕檢查清單。
常見問題
ITMS-90034 是 App Review 的拒絕嗎?
不是。這是上傳 build 時的自動驗證,發生在 TestFlight 和任何審查之前。沒有人打開過你的 app:Apple 只是發現它的簽署不是來自有效的發佈憑證。
要修正 ITMS-90034,需要撤銷我的發佈憑證嗎?
只有在憑證外洩或本來就已失效時才需要。撤銷一個正常運作的憑證,會讓你的描述檔失效,卻沒有解決根本原因。先用 codesign 檢查 IPA 的簽署,再依照決策表指出的問題修正。
可以用遠端更新修正 ITMS-90034 嗎?
不行。簽署是二進位檔的一部分,被拒絕的 build 永遠無法使用。你必須產生一個正確簽署的新二進位檔,然後重新上傳。
為什麼錯誤訊息提到的是我的 widget,而不是我的 app?
因為 widget 是獨立的 bundle,用它自己的描述檔簽署。如果它沒有向 EAS 宣告,或是用別的方式簽署,就會讓整個上傳失敗。在你的設定中宣告這個擴充功能,然後重新 build。
如果 codesign 說一切都有效,該怎麼辦?
也要檢查內嵌的描述檔和每個擴充功能。如果全部都沒問題,就用新的 build 號碼重新上傳一次。如果錯誤還是存在,就向 Apple 提交回報,附上 IPA、codesign 的輸出和上傳日誌。

