ITMS-90034 오류 해결: Missing or invalid signature
글: Mehdi Azizi
게시, 8분
ITMS-90034는 빌드가 유효한 배포 인증서로 서명되지 않았다는 뜻이에요. codesign으로 서명을 확인하고 EAS로 스토어 빌드를 다시 만드세요.
ITMS-90034는 빌드를 App Store Connect로 보낼 때 나타나요. 앱이나 앱 구성 요소 중 하나가 Apple 제출 인증서, 즉 유효한 배포 인증서로 서명되지 않았다는 뜻이에요. 해결 방법은 어느 번들이 왜 잘못 서명됐는지 찾은 다음, App Store용으로 서명된 빌드를 다시 만드는 거예요.
이 글은 오류 자체에만 집중해요. 인증서와 프로파일이라는 말이 아직 낯설다면 먼저 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 Store Connect로 보낼 때 써요.
메시지에 나온 경로를 읽으세요. 그게 문제 있는 번들이에요. Payload/MyApp.app은 앱 자체를 가리켜요. .appex로 끝나는 경로는 위젯 같은 익스텐션을 가리키고, .framework로 끝나면 포함된 라이브러리를 가리켜요.
리뷰어의 리젝이 아니에요. 검증은 업로드할 때나 빌드 처리 중에, TestFlight 전에 실패해요. 이 빌드는 테스터에게 절대 도달하지 못해요.
판단 트리: 메시지에서 해결까지
각 행은 메시지, 다음 섹션의 명령어, 또는 EAS 로그에서 읽을 수 있는 단서예요. 순서대로 확인하세요. 처음 일치하는 행이 원인이에요.
| 보이는 것 | 예상 원인 | 해결 |
|---|---|---|
.appex로 끝나는 경로 | 익스텐션 서명 오류 | 익스텐션 선언 |
Signature=adhoc | 서명되지 않은 빌드 | store 프로필로 빌드 |
Apple Development | 개발 빌드 | store 프로필로 빌드 |
ProvisionedDevices 있음 | 내부 빌드(ad hoc) | store 프로필로 빌드 |
sealed resource | 빌드 후 수정된 IPA | 빌드 다시 만들기 |
| EAS: "no longer valid" | 폐기된 인증서 | 새 인증서 |
| 모두 유효함 | Apple 측 문제 | 재전송 후 신고 |
명령어 네 개로 IPA 검사하기
expo.dev의 빌드 페이지에서 IPA를 내려받고, Mac에서 터미널을 여세요.
1. 누가 앱에 서명했나요?
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:가 보이면 개발 빌드예요. Authority 줄 없이 Signature=adhoc만 보이면 바이너리가 어떤 인증서로도 서명되지 않은 거예요.
2. 서명 후에 앱이 수정됐나요?
codesign --verify --deep --strict -vv ipa/Payload/*.app
valid on disk, 그다음 satisfies its Designated Requirement가 나와야 해요. TN3161은 이 검사가 보장하는 것을 설명해요. 예상한 파일이 모두 있고, 추가된 파일도 수정된 파일도 없다는 거예요. 제가 서명한 뒤 손댄 테스트 번들에서는 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 프로파일, 즉 내부 빌드용이에요. 세 번째 줄은 프로파일 만료일을 보여 줘요.
4. 익스텐션과 프레임워크도 똑같이 서명됐나요?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
모든 구성 요소가 앱과 같은 Authority 줄을 보여야 해요. 다른 게 하나 있다면, 메시지가 가리키는 게 바로 그거예요.
업로드 전에 확인하고 싶다면 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로 원인별로 고치기
내부 빌드나 개발 빌드를 Apple에 보낸 경우
eas.json에 관한 Expo 문서에 따르면 "distribution": "internal" 빌드는 스토어용으로 서명되지 않고 ad hoc 프로파일을 써요. 기본값인 store 배포 프로필만 업로드 가능한 빌드를 만들어요. 가장 안전한 방법은 직접 고르지 말고 방금 만든 빌드를 그대로 보내는 거예요.
eas build --platform ios --profile production --auto-submit
eas submit --path를 쓴다면 그 파일이 정말 최신 store 빌드인지 확인하세요. Apple 포럼에서 한 팀은 업로드 도구가 git에 커밋된 예전 IPA를 매번 보내고 있었다는 걸 알게 됐어요.
익스텐션을 빠뜨린 경우
익스텐션은 각각 별도의 번들이고, 자기 식별자와 자기 프로파일이 있어요. 네이티브 코드를 생성하는 Expo 프로젝트라면 iOS 익스텐션에 관한 Expo 문서대로 extra.eas.build.experimental.ios.appExtensions에 선언해야 해요. 그러면 EAS CLI가 빌드 전에 익스텐션을 알고, 자격 증명을 만들거나 검증해요. 익스텐션을 추가하는 라이브러리 대부분은 플러그인으로 이 선언을 대신 써 줘요.
미니게임 알람 앱인 Solys에는 익스텐션이 네 개 있어요. 위젯 하나와 스크린 타임 익스텐션 세 개예요. 네 개 모두 설정에 선언돼 있고, EAS가 각각의 프로파일을 갖고 있어요. 이 선언 없이 Xcode에서 손으로 추가한 익스텐션은 메시지에 .appex 경로가 나올 때 가장 유력한 범인이에요.
인증서가 폐기됐거나 만료된 경우
인증서에 관한 Apple 페이지는 분명하게 말해요. 만료되거나 폐기된 인증서로 서명된 빌드는 더 이상 업로드할 수 없어요. 이미 업로드했지만 아직 제출하지 않은 빌드도 인증서가 폐기되면 Invalid Binary 상태가 될 수 있어요.
EAS CLI 24.10.0 코드를 보면 이 문제가 언제 눈에 띄지 않고 넘어가는지 알 수 있어요.
- Apple에 로그인한 대화형 빌드: EAS가 인증서를 Apple에 아직 유효한 인증서들과 비교해요. 없으면 "Current distribution certificate is no longer valid in Apple Dev Portal"을 표시하고 인증서를 고르거나 새로 만들게 해요.
- 로그인하지 않은 대화형 빌드: EAS는 날짜만 확인하고 Apple 쪽 검증을 건너뛴다고 알려요.
- CI에서 돌리는 비대화형 빌드: EAS는 "Distribution Certificate is not validated for non-interactive builds"를 표시하고 그대로 서명해요.
CI에서는 EAS가 인증서 자체를 다시 확인하지 않아요. 그래서 폐기 사실이 업로드할 때에야 드러날 수 있어요. 해결 방법은 Apple 계정에 로그인한 대화형 빌드를 돌리거나, eas credentials --platform ios에서 Build Credentials 메뉴로 가서 "Distribution Certificate: Add a new one to your account"를 고르는 거예요. 예전 인증서가 들어 있던 프로파일은 무효가 돼요. EAS가 다음 빌드 때 확인하고 다시 만들어요. 인증서 개수에 대한 Apple의 제한은 iOS 개발자 인증서 가이드에 자세히 있어요.
서명 후 바이너리를 수정한 경우
Apple 기술 노트 TN3126에서 설명하듯, 서명은 코드, 리소스, 메타데이터를 해시로 봉인해요. IPA 압축을 풀어 파일을 바꾸고 다시 압축하면 이 봉인이 깨져요. 수정은 설정에서 하고 빌드를 다시 만드세요. EAS가 만든 IPA에는 절대 손대지 마세요.
.zip 압축 파일 안처럼 엉뚱한 위치에 둔 코드도 마찬가지예요. App Store가 다시 서명할 수 없어요. 허용되는 위치는 Apple의 번들 콘텐츠 페이지에 나와 있어요.
로컬 자격 증명을 쓰는 경우
EAS 프로필이 "credentialsSource": "local"을 쓴다면 credentials.json 파일이 .p12 인증서와 .mobileprovision 프로파일을 가리켜요. 3단계 명령어로 프로파일을 확인하세요. App Store 유형이어야 하고, 현재 배포 인증서가 들어 있어야 해요. 그리고 이 파일들은 Expo 앱의 API 키처럼 저장소 밖에 두세요.
모두 유효한 경우
답답한 경우가 하나 남아요. Apple 포럼에서는 아무것도 바꾸지 않고 같은 빌드를 다시 보냈더니 오류가 사라졌다는 개발자들이 있어요. 2026년 8월과 9월에는 반대 사례를 다룬 스레드가 두 개 있었어요. 인증서와 프로파일을 새로 만들고 서명도 확인했는데 계속 실패했다는 거예요. 그중 한 스레드에서 Apple 엔지니어는 IPA, 서명 분석 결과, Transporter 로그를 첨부해 버그 리포트를 보내고 App Store Connect에 문의하라고 권했어요.
그러니 새 빌드 번호로 한 번 다시 보내 보세요. 네 가지 명령어 결과가 깨끗한데도 오류가 다시 나오면 이 자료를 첨부해 Apple에 신고하세요. 반사적으로 인증서를 폐기하지 마세요. 더 해결되는 건 없고 프로파일만 무효가 돼요.
낭패 없이 빌드 보내기
서명은 업로드 전에 2분이면 확인할 수 있어요. 다른 자동 검사도 똑같이 꼼꼼하게 챙겨야 해요. Xcode 버전에 관한 ITMS-90725, 권한 설명 문구에 관한 ITMS-90683이 그래요. Mac 없이 빌드부터 업로드까지 하는 전체 과정은 Mac 없이 iOS 앱 출시하기에 있어요.
리뷰어의 리젝은 좀 더 한 발 물러서서 봐야 해요. 대응 방법은 Apple에 앱이 리젝됐을 때 페이지에, 가장 흔한 사유는 Apple이 앱을 리젝하는 이유에 정리해 뒀어요.
업로드 전에 준비 상태를 점검하고 싶다면 Review Kit에 제 체크리스트와 프로젝트를 검토해 주는 Claude Code 스킬을 모아 뒀어요. 업로드가 막혀서 사람의 눈이 필요하다면 저와 한 시간 예약하세요. 화상으로 화면을 보면서 프로젝트를 함께 살펴봐요. 첫 출시를 준비 중이라면 무료 진단을 받아 보세요. 단계를 순서대로 정리해 주고 Apple 리젝 방지 체크리스트도 보내 드려요.
자주 묻는 질문
ITMS-90034는 App Review 리젝인가요?
아니요. 빌드를 보낼 때, TestFlight와 모든 심사 전에 이뤄지는 자동 검증이에요. 아무도 앱을 열어 보지 않았어요. Apple은 서명이 유효한 배포 인증서에서 온 게 아니라는 것만 확인했어요.
ITMS-90034를 고치려면 배포 인증서를 폐기해야 하나요?
인증서가 유출됐거나 이미 무효인 경우에만요. 잘 작동하는 인증서를 폐기하면 원인은 그대로인 채 프로파일만 무효가 돼요. 먼저 codesign으로 IPA 서명을 읽고, 판단 트리가 가리키는 문제를 고치세요.
원격 업데이트로 ITMS-90034를 고칠 수 있나요?
아니요. 서명은 바이너리의 일부이고, 거부된 빌드는 절대 쓸 수 없어요. 제대로 서명된 새 바이너리를 만들어 다시 보내야 해요.
왜 오류가 앱이 아니라 위젯을 가리키나요?
위젯은 자기 프로파일로 서명되는 별도의 번들이기 때문이에요. EAS에 선언되지 않았거나 다른 방식으로 서명됐다면 업로드 전체가 실패해요. 설정에 익스텐션을 선언하고 빌드를 다시 만드세요.
codesign이 모두 유효하다고 하면 어떻게 하나요?
포함된 프로파일과 각 익스텐션도 확인하세요. 모두 깨끗하다면 새 빌드 번호로 한 번 다시 보내세요. 그래도 오류가 계속되면 IPA, codesign 출력, 업로드 로그를 첨부해 Apple에 리포트를 보내세요.

