Skip to content

flutter build ipa fails for manual signing unless a custom ExportOptions.plist is provided (Push Notifications / Sign in with Apple entitlements) #177853

@MohammedTarigg

Description

@MohammedTarigg

Problem Statement

The flutter build ipa command fails during the export step when using manual code signing for iOS release or profile builds that include Push Notifications and Sign in with Apple entitlements. The archive step succeeds, but the export fails due to an incomplete ExportOptions.plist configuration.

Reproduction Steps

  1. Configure an iOS project with manual code signing:

    • Set CODE_SIGN_STYLE = Manual in Xcode project settings
    • Set PROVISIONING_PROFILE_SPECIFIER to a distribution profile name or UUID
    • Configure the app with Push Notifications and Sign in with Apple entitlements
  2. Run:

    flutter build ipa --release
  3. Result:

    • ✅ Archive step completes successfully
    • ❌ Export step fails:
      error: exportArchive: "Runner.app" requires a provisioning profile with the Push Notifications and Sign in with Apple features.
      

Root Cause

The provisioning profile contains the required entitlements. The failure occurs because xcodebuild -exportArchive requires a complete ExportOptions.plist with teamID and provisioningProfiles mapping when using manual signing. Flutter's default generated plist only includes method and uploadBitcode, which is insufficient.

Current Workaround

Manually create an ExportOptions.plist with:

  • method = app-store (or ad-hoc, enterprise, etc.)
  • teamID = <TEAM_ID>
  • signingStyle = manual
  • provisioningProfiles = { "<bundle id>": "<profile UUID>" }

Then run:

flutter build ipa --release --export-options-plist=ios/ExportOptions.plist

This succeeds and produces a valid IPA.

Impact

Developers using manual code signing for App Store distribution with Push Notifications and/or Sign in with Apple entitlements are blocked. This requires manual creation and maintenance of ExportOptions.plist files, adding friction to development workflows and CI/CD pipelines.

Related issues:

Proposed Solution

Auto-generate a complete ExportOptions.plist for manual signing configurations when:

  • CODE_SIGN_STYLE=Manual is detected (Release or Profile builds)
  • A valid provisioning profile can be located and parsed
  • Only for the main app target (not extensions/widgets)

The generated plist will respect the user's export method choice:

  • Export method: whatever the user specified with --export-method (app-store, ad-hoc, enterprise, etc.)
  • Team ID: from the project's DEVELOPMENT_TEAM setting
  • Signing style: "manual"
  • Provisioning profiles: auto-detected from system profiles

Fallback behavior:

  • If profile lookup fails or conditions aren't met, use current behavior (simple plist)
  • Automatic signing: unchanged
  • Debug builds: unchanged
  • Multi-target apps: unchanged

Testing Instructions

To verify the fix:

  1. Create an iOS app with CODE_SIGN_STYLE=Manual and Push Notifications entitlements
  2. Run flutter build ipa --release --verbose
  3. Verify ExportOptions.plist contains:
    • teamID (from DEVELOPMENT_TEAM setting)
    • signingStyle = "manual"
    • provisioningProfiles mapping with correct profile UUID

Questions for Maintainers

  1. Is this scoped approach acceptable for inclusion in flutter_tools?
  2. Should this enhancement support multiple targets (extensions/widgets) in a future iteration, or is the single-target scope sufficient for v1?

Feedback welcome. I have a working implementation with comprehensive unit tests ready for PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: buildBuilding flutter applications with the toolplatform-iosiOS applications specificallyr: duplicateIssue is closed as a duplicate of an existing issueteam-iosOwned by iOS platform teamtoolAffects the "flutter" command-line tool. See also t: labels.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions