XcodeのGUIではArchiveできるのに、SSHからflutter build ipaを実行すると署名で止まる。
最短ルートは証明書の再発行ではありません。まず失敗段階を分け、次にTeam、Target、Provisioning Profile、Keychainを確認し、最後にRelease Archive、IPA、実際のアップロードまで順に通します。
01対象読者と最初の切り分け
WindowsやLinuxでFlutterアプリを書き、iOS公開だけをリモートMacに任せている独立開発者向けです。Flutter 3.44への更新後にRunnerやプラグインTargetで署名エラーが出た場合にも使えます。
SSH、スクリプト、CIからflutter build ipaを無人実行したい小規模チームは、特にKeychainの確認を先に行ってください。FlutterのiOSリリースにはmacOS、Xcode、Appleのコード署名環境が必要です。公式のFlutter iOSビルド・リリース手順と、Flutter 3.44.0の公式リリースノートを基準にします。
たとえば、ログが次のように見えるとします。
[✓] Xcode build finished
error: No signing certificate "iOS Distribution" found
error: code signing failed for target 'Runner'
Command PhaseScriptExecution failed with a nonzero exit code
ここで最後のcodesignだけを見てはいけません。Flutterのビルド、Xcode Build、Archive、IPA書き出し、署名検証、アップロードは別の段階です。最初に確認する項目は次の4つです。
- 最初に発生した有効なエラー
- 失敗したTarget
- ReleaseかDebugかというBuild Configuration
- Xcode GUI、Flutter CLI、SSHのどの入口で失敗したか
Flutter 3.44のプロジェクトでも、まず同じコミットをGUIとCLIで比較します。GUIだけ成功する場合は、プロジェクト全体よりも実行ユーザーやKeychainを疑います。
02署名失敗を段階別に分ける
Runner設定
RunnerのTeam、Bundle ID、Release設定、Schemeを同時に確認します。開発者アカウント側のApp IDと、Xcodeプロジェクト内のBundle IDが異なると、正しい証明書があってもProfileを選べません。
flutter build ipaがDevelopment Teamの選択を求める場合、CLIが参照するSchemeにTeamが設定されていない、またはRelease設定だけ別の値になっている可能性があります。XcodeでRunnerを選び、Signing & CapabilitiesのTeam、Bundle Identifier、Automatically manage signingの状態を確認してください。
自動署名から手動署名へ切り替える場合は、RunnerだけでなくTargetとExport設定も同じ方針にそろえます。意図なく混在させると、GUIとCLIが異なるProfileを選ぶ原因になります。
証明書と秘密鍵
証明書ファイルをインポートしただけでは、署名できるとは限りません。Keychainには証明書と、それに対応する秘密鍵がペアで存在する必要があります。Appleは証明書の種類と用途を証明書の概要で説明しています。
確認する対象は4つです。
- 証明書ファイルが存在するか
- 対応する秘密鍵が同じKeychainにあるか
- 署名IDとして表示されるか
- Release用の用途と現在の作業が一致しているか
Provisioning Profileは単なる設定ファイルではありません。App ID、配布種別、証明書、Capabilitiesの組み合わせを確認します。Profileの内部構造については、Appleのコード署名とProvisioning Profileの技術説明が基準になります。
証明書の失効、Profileの削除、Keychainの初期化は最後に行います。先に既存ファイルを保管し、他のビルドマシンや審査中のビルドに影響しないことを確認してください。復旧できるバックアップがない状態で削除すると、別環境の署名まで止まります。
03Targetとentitlementsの不一致
Runnerが通っても、通知拡張、Widget、Share Extension、プラグイン由来の埋め込みTargetで失敗することがあります。TargetごとにBundle ID、Team、Signing & Capabilities、entitlementsを確認してください。
RunnerとプラグインTargetは、必ず同じBundle IDや同じProfileを使うわけではありません。親アプリと拡張機能では識別子が異なることがあり、それぞれに対応した署名資産が必要です。
IPA生成後は、ソース設定だけでなくArchive内の実体を確認します。Appleのentitlementsリファレンスを参照し、Profileが許可していないCapabilityが最終成果物に含まれていないかを調べます。
04注意:IPAが出力されたという事実だけでは、配布可能とは判定できません。Archive、署名、entitlements、検証、アップロードを別々の合格条件として記録してください。
リモートMacのKeychainと実行権限
Xcodeの画面では成功し、SSHだけでFlutter 3.44 署名失敗になる場合、最初に非対話式Keychainアクセスを確認します。GUIセッションとSSHセッションでは、ログインユーザー、既定Keychain、ロック状態、秘密鍵へのアクセス許可が異なることがあります。
次の順番で比較してください。
- GUIで同じコミットとRelease SchemeをArchiveする。
- GUIのターミナルで同じ
flutter build ipaを実行する。 - SSHで同じユーザー、同じ作業ディレクトリから実行する。
- CIや定期タスクで実行し、失敗したTargetと署名IDを記録する。
- 各セッションで既定Keychain、ロック状態、証明書と秘密鍵の存在を確認する。
SSHだけが失敗した場合、証明書の再発行より、Keychainのロック解除とアクセス制御の範囲を見直します。秘密鍵へのアクセスを全タスクに許可するのではなく、対象ユーザーと対象ジョブに限定してください。Appleのコード署名に関する開発者フォーラムの排障情報も、SSH環境の確認材料になります。
Keychainのリセットや秘密鍵の再インポートを行うと、同じMac上の他プロジェクトにも影響する可能性があります。変更前のKeychain、Profile、設定ファイルを保存し、失敗した場合に元へ戻せる状態を作ってから実施します。
05Release検証の合格条件
修正対象を決めるときは、次の判定リストを上から順に使ってください。条件に当てはまる項目だけを修正し、すべての証明書やキャッシュを一度に削除しないことが重要です。
- [ ] GUIとSSHの両方でArchiveが失敗する
→ Runner、Bundle ID、Target、Provisioning Profile、entitlementsの順にプロジェクト設定を修正します。 - [ ] GUIは成功し、SSHだけが失敗する
→ 証明書を作り直す前に、Keychain、実行ユーザー、セッション、秘密鍵のアクセス範囲を修正します。 - [ ] Runnerは成功し、拡張Targetだけが失敗する
→ 該当Target専用のBundle ID、Capabilities、Provisioning Profileを照合します。 - [ ] Archiveは成功し、IPA検証で失敗する
→ Export設定と、Archive内の最終entitlementsを確認します。 - [ ] IPA検証は成功し、アップロードで失敗する
→ 配布先、認証情報、App Store側の識別子を確認します。 - [ ] 再起動や接続切断後に再現できない
→ 常駐のiOS打ち包み環境としては、まだ合格と判断しません。
XcodeのArchiveと分配手順はAppleの公式分配ガイドに沿って確認します。さらに配布準備の公式資料で、署名と提出前の条件を照合してください。
最終的な確認手順は次のとおりです。
- 同じコミットで
flutter build ios --releaseを実行する。 - Release Archiveを作成し、Runnerと埋め込みTargetを確認する。
- ArchiveからIPAを書き出す。
- 署名とentitlementsを成果物側で検証する。
- App Store Connectへの実際のアップロードを行う。
- SSH切断、再接続、再起動後にも同じ手順を再実行する。
Xcodeだけで成功しても、SSHのflutter build ipaと再接続後の実行が安定しないなら、問題はプロジェクトではなく環境側に残っています。
リモートMacを選ぶ判断
現在のPCでXcodeの確認はできても、長時間のArchive、証明書管理、アップロード、再実行を維持できない場合があります。WindowsやLinuxを中心に開発しているなら、VpsMeshのMacレンタル環境で同じリポジトリを使い、まずArchive、IPA、検証、アップロードまで確認する方法があります。
利用するMacの候補や運用条件を先に比較したい場合は、Macレンタルの利用ポリシーも確認してください。署名鍵を置く環境では、接続方法だけでなく、利用者の権限、Keychainの保持、作業終了後の削除範囲まで決めておく必要があります。
自前のMacでは、初期費用、空き容量、電源管理、外部からの接続維持が負担になります。一方、リモートMacでは、Keychainの永続性、SSHユーザー、GUIセッションの有無、秘密鍵の保護を自分で設計する必要があります。短期のリリースや既存環境の代替ならレンタルが合いますが、長期の常時高負荷処理や物理USB機器が必要な場合は、自前Macの方が適しています。
現在の環境で署名が通らないたびに証明書を再発行すると、原因が隠れ、他のビルドマシンまで壊すことがあります。まず同じプロジェクトを権限とKeychainを管理できるMacで再現し、成功条件を記録してから、短期レンタルか常設環境かを決めてください。
よくある確認
FAQでは、Flutter CLIとXcodeの設定差、Targetごとの署名、IPA生成後のentitlements不一致を分けて確認します。特に「ファイルができた」ことと「配布できる」ことを同じ意味にしないでください。
07まとめ
Flutter 3.44 署名失敗の初動は、証明書の全交換ではありません。失敗段階、Runner設定、Target、署名資産、リモートMacのKeychainを分離し、Release Archiveから実アップロードまで検証します。
本記事は2026年9月7日に更新しました。Flutter公式の3.44.0リリースノート、iOSデプロイ文書、Appleの証明書、Provisioning Profile、entitlements、配布資料を照合しています。XcodeやFlutter、Apple側の手順が更新された場合は、同じ確認順序を再確認してください。