Flutter 앱을 개발하고 iOS 앱스토어에 배포하거나 TestFlight에 올리려고 할 때, Failed to codesign 오류는 개발자들의 가장 큰 골칫거리 중 하나입니다. 특히 Warning: unable to build chain to self-signed root 또는 errSecInternalComponent와 같은 메시지가 함께 나타난다면, 단순한 설정 문제를 넘어선 복합적인 원인일 가능성이 큽니다.
저 역시 이 문제로 며칠 밤낮을 고생하며 Xcode, Flutter SDK 재설치는 물론, 키체인 초기화까지 시도했습니다. 이 글은 그 모든 과정을 거쳐 마침내 문제를 해결한 경험과 노하우를 담고 있습니다. 같은 문제로 고통받는 분들에게 이 글이 도움이 되기를 바랍니다.
🧐 문제의 증상
flutter build ipa 또는 Xcode에서 아카이브(Archive) 시도 시 다음과 유사한 오류 메시지가 나타납니다.
error: Target release_unpack_ios failed: Exception: Failed to codesign /Users/yourusername/Library/Developer/Xcode/DerivedData/.../Flutter.framework/Flutter with identity [인증서 ID].
/Users/yourusername/Library/Developer/Xcode/DerivedData/.../Flutter.framework/Flutter: replacing existing signature
Warning: unable to build chain to self-signed root for signer "Apple Distribution: Your Name (Team ID)"
/Users/yourusername/Library/Developer/Xcode/DerivedData/.../Flutter.framework/Flutter: errSecInternalComponent
Failed to package /Users/yourusername/project/your_flutter_app.
특히 주목해야 할 부분은 다음과 같습니다.
- Failed to codesign ... Flutter.framework/Flutter: Flutter.framework 파일에 대한 코드 서명 실패.
- Warning: unable to build chain to self-signed root: Apple의 인증서 체인이 제대로 신뢰되지 않음.
- errSecInternalComponent: macOS 보안 서비스 내부 구성 요소 오류.
💡 문제의 원인 분석
이러한 복합적인 오류 메시지는 주로 다음 세 가지 문제의 조합으로 발생합니다.
- 키체인 내 인증서 중복 및 혼란: 로그인 키체인에 동일한 이름의 인증서가 여러 개 존재하거나, 만료된 인증서, 또는 Apple의 중간/루트 인증서가 잘못된 키체인에 설치되어 있을 때 발생합니다.
- Apple 인증서 체인 신뢰 문제: Apple Worldwide Developer Relations Certification Authority와 같은 Apple의 중간 인증서나 Apple Root CA - G3 같은 루트 인증서가 시스템에서 신뢰할 수 없는 상태로 설정되어 있을 때 unable to build chain 오류가 발생합니다.
- Xcode 및 Flutter 빌드 캐시 손상: 이전 빌드 과정에서 생성된 캐시 파일이나 임시 파일들이 꼬여서 올바른 코드 서명 과정을 방해합니다.
✅ 해결 과정: 단계별 완벽 가이드
문제를 해결하기 위해 다음 단계를 반드시 순서대로, 꼼꼼하게 따라야 합니다.
1. 🔑 키체인 접근(Keychain Access) 완벽 정리
가장 중요한 단계입니다. Mac에 설치된 모든 개발 관련 인증서와 Apple 루트/중간 인증서를 깨끗하게 정리하고 올바르게 설정해야 합니다.
- 키체인 접근 열기: Command + Space로 Spotlight 검색을 열고 "키체인 접근" 검색 후 실행.
- 로그인 키체인 > 나의 인증서 정리:
- 좌측 사이드바에서 로그인 키체인을 선택하고, 카테고리에서 **나의 인증서**를 클릭합니다.
- Apple Distribution: [내 이름 (팀 ID)] 인증서가 여러 개 있다면, 가장 최신이고 아래에 개인 키가 연결된 유효한 인증서 하나만 남기고 나머지는 모두 삭제합니다.
- Apple Development: [내 이름 (팀 ID)] 인증서도 동일하게 유효한 하나만 남기고 모두 삭제합니다.
- iPhone Distribution: [내 이름] 또는 iPhone Developer: [내 이름] 등 오래된 또는 중복된 인증서는 모두 삭제합니다.
- 로그인 키체인 > 인증서 정리:
- 좌측 사이드바에서 로그인 키체인을 선택하고, 카테고리에서 인증서 (나의 인증서 아님)를 클릭합니다.
- Apple Root CA - G3 인증서가 있다면 삭제합니다. 이 인증서는 시스템 루트 키체인에만 있어야 합니다.
- Apple Worldwide Developer Relations Certification Authority 인증서 중 만료일이 2030년 2월 20일인 구버전은 삭제합니다. 2036년 3월 19일 만료인 G6 버전만 남깁니다.
- 시스템 루트 키체인 확인 및 신뢰 설정:
- 좌측 사이드바에서 시스템 루트 키체인을 선택하고 인증서 카테고리를 클릭합니다.
- Apple Root CA - G3 인증서가 있는지 확인하고, 더블클릭하여 상세 정보를 엽니다. 신뢰 섹션에서 **"이 인증서 사용 시:"**를 항상 신뢰 (Always Trust) 로 설정합니다. (대부분의 경우 이미 설정되어 있을 것입니다.)
- Apple Worldwide Developer Relations Certification Authority (2036년 3월 19일 만료 G6 버전) 인증서를 찾습니다.
- 이 인증서를 더블클릭하여 상세 정보를 엽니다. 신뢰 섹션에서 "이 인증서 사용 시:" 옵션이 시스템 기본 설정 사용으로 되어 있을 것입니다. 이를 클릭하여 항상 신뢰 (Always Trust) 로 변경합니다. Mac 비밀번호를 입력하여 저장합니다.
- 두 인증서 모두 녹색 체크 표시와 함께 "이 인증서가 유효함"으로 표시되어야 합니다.
- 사용자 개발/배포 인증서의 접근 제어 설정:
- 로그인 키체인 > 나의 인증서 카테고리로 돌아갑니다.
- 남겨둔 Apple Distribution: MyoungBo Seo 인증서와 Apple Development: MyoungBo Seo 인증서를 각각 더블클릭합니다.
- 접근 제어 탭으로 이동하여 "모든 응용 프로그램이 이 항목에 접근하도록 허용" 옵션이 선택되어 있는지 최종적으로 확인합니다. (만약 이 옵션이 선택 불가하면, 아래 "이 응용 프로그램들이 이 항목에 접근하도록 허용"을 선택하고 반드시 /usr/bin/codesign과 /Applications/Xcode.app이 목록에 추가되어 있는지 확인 후 저장).
2. 🌐 Apple Developer 웹사이트 정리 및 프로파일 재생성
Mac의 키체인을 정리했으므로, Apple Developer 웹사이트의 정보도 일치시켜야 합니다.
- Apple Developer 웹사이트 로그인: developer.apple.com
- Certificates, IDs & Profiles > Certificates:
- 현재 키체인에 남겨둔 유효한 Apple Distribution (Type: Distribution, Platform: All) 및 Apple Development (Type: Development, Platform: All) 인증서를 제외한 모든 오래된/중복된 인증서 (특히 iOS Distribution, iOS Development 등 구형 타입)를 선택하여 Revoke (폐기) 합니다.
- Certificates, IDs & Profiles > Profiles:
- 기존의 모든 Provisioning Profile을 Revoke (폐기) 합니다.
- 새로운 App Store 배포용 Provisioning Profile을 생성합니다. (Distribution > App Store 선택).
- 이때 새로 정리해서 남겨둔 Apple Distribution: MyoungBo Seo (9NYRJZL6SS) 인증서를 선택하여 프로파일과 연결합니다.
- 생성된 프로파일을 다운로드하여 Mac에 설치합니다 (더블클릭).
3. 🧹 Xcode 및 Flutter 빌드 환경 철저한 클린 빌드
이제 Mac과 Apple Developer 계정의 인증서 설정이 깨끗해졌으므로, 빌드 환경을 완벽하게 초기화합니다.
- Xcode 완전히 종료: Command + Q
- Flutter 클린: 터미널에서 Flutter 프로젝트 루트 폴더로 이동하여 실행합니다.
-
Bash
flutter clean
- Xcode Derived Data 완전 삭제:
- Finder를 열고 Command + Shift + G를 누릅니다.
- ~/Library/Developer/Xcode/DerivedData/ 경로를 입력하고 이동합니다.
- 이 폴더 안에 있는 모든 폴더를 과감하게 삭제합니다.
- CocoaPods 완전 정리 및 재설치:
- Flutter 프로젝트의 ios 폴더로 이동합니다:
-
Bash
cd /Users/myeongboseo/project/flutter/doongdoong_talk/ios
- 기존 Pods 구성을 완전히 제거하고 캐시를 정리합니다:
-
Bash
pod deintegrate rm -rf Pods Podfile.lock # Pods 폴더와 Podfile.lock 파일까지 완전히 삭제 rm -rf ~/Library/Caches/CocoaPods # CocoaPods 캐시 자체도 삭제
- Pods를 다시 설치합니다:
-
Bash
pod install
- 다시 Flutter 프로젝트 루트로 돌아옵니다:
-
Bash
cd ..
- Xcode 프로젝트 다시 열기: /Users/myeongboseo/project/flutter/doongdoong_talk/ios/Runner.xcworkspace 파일을 Xcode로 엽니다.
- Xcode 내에서 Product > Clean Build Folder 수행.
- Xcode Signing & Capabilities 탭 설정 재확인:
- Runner 프로젝트 선택 > General 탭 > Signing 섹션.
- Automatically manage signing이 체크되어 있다면, 체크 해제 후 다시 체크하여 Xcode가 설정을 새로고침하도록 합니다.
- 올바른 팀(Team)이 선택되었는지 확인합니다.
- Signing Certificate가 올바른 인증서 (예: Apple Distribution: MyoungBo Seo (9NYRJZL6SS))로 녹색 체크 표시와 함께 유효하게 나타나는지 확인합니다.
🚀 마지막 시도! 빌드 실행
이제 모든 준비가 완료되었습니다. 터미널에서 다시 빌드를 시도합니다.
flutter build ipa
이 모든 단계를 꼼꼼히 거치셨다면, Failed to codesign, unable to build chain to self-signed root, errSecInternalComponent 오류로부터 해방되어 성공적으로 앱을 빌드하실 수 있을 겁니다.
이 과정이 매우 복잡하고 시간이 많이 소요되었지만, 한 번 제대로 설정해두면 다음부터는 훨씬 수월하게 개발 및 배포를 진행할 수 있을 것입니다.
Happy Coding! 🎉