Privacy

    Why does ITMS-91056 flag Reachability.framework's manifest?

    App Store Connect upload pipeline rejecting an IPA with ITMS-91056 because the PrivacyInfo.xcprivacy inside Reachability.framework fails schema validation

    You uploaded an IPA to App Store Connect, the processing email arrived ten minutes later, and the body listed ITMS-91056 with a path containing Reachability.framework. The file Apple flagged is not one you wrote. It was bundled by a dependency that ships its own PrivacyInfo.xcprivacy, and something inside that file did not pass the upload validator.

    Short answer

    ITMS-91056 is a processing error Apple returns when a PrivacyInfo.xcprivacy file inside a framework or resource bundle in your IPA contains keys or values that fail schema validation. With Reachability.framework the offending file usually sits at Frameworks/Reachability.framework/ReachabilitySwift.bundle/PrivacyInfo.xcprivacy and was added by an older release of the library before the manifest format settled. The repair belongs to the dependency author, not to your root manifest, so the practical responses are: update the package, switch to a maintained fork, or strip the file in a build phase as a temporary measure.

    What you should know

    • ITMS-91056 is a format error, not a tracking declaration error. Apple's validator parses the plist against the documented privacy manifest schema and rejects anything with an unknown key, a wrong value type, or a malformed string.
    • The path in the email names the framework that owns the bad file. For Reachability that path typically includes ReachabilitySwift.bundle/PrivacyInfo.xcprivacy, embedded inside Reachability.framework.
    • Your top-level PrivacyInfo.xcprivacy is a separate file. Editing the one at the root of your .app bundle does nothing for SDK manifests buried under Frameworks/.
    • Enforcement started on 2024-05-01. Apple shifted privacy manifest checks from warnings to hard upload rejections for builds submitted through App Store Connect.
    • Reachability.framework reaches you through several wrappers. It is pulled in by Flutter's connectivity_plus, by several CocoaPods specs, and by Swift Package Manager versions of Reachability.swift published before the schema stabilized.

    What does ITMS-91056 actually mean when Apple sends it?

    The short answer is that Apple's upload pipeline runs each PrivacyInfo.xcprivacy file inside the IPA through a schema validator. When the validator finds an invalid key, a value of the wrong type, or a missing required attribute, it returns ITMS-91056 and names the offending path. The code does not care whether the declared categories are truthful. It only checks that the file is well-formed against the published schema.

    Apple documents the manifest in Privacy manifest files. A valid manifest is a property list with four top-level keys: NSPrivacyTracking (boolean), NSPrivacyTrackingDomains (array of strings), NSPrivacyCollectedDataTypes (array of dictionaries), and NSPrivacyAccessedAPITypes (array of dictionaries with NSPrivacyAccessedAPIType and NSPrivacyAccessedAPITypeReasons keys). Any other top-level key, or a value of the wrong type, fails the validator.

    In practice the failures inside third-party frameworks fall into a handful of patterns: the bundled file declares a reason code that Apple later renamed or removed, the NSPrivacyAccessedAPIType string uses casing that does not match the schema, or the file ships as a binary plist when only XML plist is accepted at that location. Each of those reasons returns the same ITMS-91056. The fact that the code looks specific is misleading. Treat it as a generic "your manifest does not parse" signal and locate the file at the path Apple named.

    Why does Reachability.framework's manifest get rejected so often?

    Reachability.framework, in its most common form, is a packaging of ashleymills/Reachability.swift, one of the older iOS networking utilities still in heavy use. The framework wraps the SystemConfiguration network reachability APIs, which sit on Apple's required-reason API list and therefore require a declaration in a privacy manifest. The library added a manifest sometime in 2024, and several pinned releases shipped a version of that file that does not parse cleanly under the current validator.

    Two factors compound the problem. The manifest is embedded inside a resource bundle (ReachabilitySwift.bundle) rather than at the framework root, which is the layout Apple expects but which means the path in the error email looks unusual to developers seeing ITMS-91056 for the first time. The dependency is also a transitive one for a lot of apps: people pulling Flutter's connectivity_plus plugin or older Pods of analytics SDKs get Reachability.framework as a sub-dependency, sometimes without realizing it. The community issue thread on Reachability.swift catalogues the variants of the message developers received during 2024 and 2025.

    The honest reading is that the framework is maintained at a slower cadence than Apple's schema changes. Apps that pin to a tagged release built before the manifest tightened up will keep hitting this until the consumer updates.

    How do you find which dependency ships the bad manifest?

    Start with the path inside the error email. The string after Frameworks/ is the framework name. If you do not recognize it, search your dependency lockfile.

    For CocoaPods, open Pods/Manifest.lock or Podfile.lock and search for the framework name. The lockfile lists every pod and its resolved version, plus the transitive dependencies. For Swift Package Manager, open Package.resolved in your .xcworkspace and look for the package by name. For Flutter, examine ios/Podfile.lock since plugin authors usually deliver the iOS half of a plugin as a pod, including connectivity_plus and similar networking helpers.

    Once you have the dependency, two facts matter: which release tag is currently resolved, and whether a newer release has shipped that touches the privacy manifest. Compare the resolved version against the changelog. If the maintainer noted a privacy manifest update after your pinned version, the upgrade likely fixes ITMS-91056. If the changelog is silent, look at the diff for PrivacyInfo.xcprivacy files between your tag and the latest tag.

    For a faster diagnosis on a finished build, unzip the IPA, open the Frameworks/ directory, and inspect each PrivacyInfo.xcprivacy with plutil -lint followed by plutil -p. Any file that fails to lint, or that contains keys outside the four documented top-level keys, is a candidate for the rejection.

    What can you change in your build to fix it before the next upload?

    The right answer is updating the dependency. When a maintained release exists that ships a corrected manifest, bump your Podfile, Package.swift, or pubspec.yaml to that version, regenerate the lockfile, and rebuild. Most ITMS-91056 reports against Reachability.framework resolve at this step.

    When no fixed release exists yet, you have two interim options. The first is to fork the dependency, repair the manifest against the Apple privacy manifest schema, and point your package manager at the fork. The second is to strip the manifest from the framework before the IPA is signed. A Run Script build phase that removes the offending file works for a tactical release:

    FW="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework"
    rm -f "${FW}/ReachabilitySwift.bundle/PrivacyInfo.xcprivacy"
    

    Stripping the file is not a long-term plan. Apple expects every SDK that accesses required-reason APIs to declare those reasons. Removing the manifest moves the responsibility to your root PrivacyInfo.xcprivacy, which then needs to cover the NSPrivacyAccessedAPICategorySystemBootTime or NSPrivacyAccessedAPICategoryFileTimestamp reasons that Reachability would otherwise declare. Treat the strip as a release-window workaround and open a ticket to remove it once the dependency lands a fix.

    Editing the SDK's manifest in place inside Pods/ works for one build but is overwritten by the next pod install. If you must patch in place, use a tool like cocoapods-patch or commit the change in a build script that runs after pod install so the repair survives reinstalls.

    How does ITMS-91056 differ from ITMS-91061 and ITMS-91065?

    The 9105x family of privacy manifest errors gets conflated often. The codes are not interchangeable.

    CodeTriggerWhere the file lives
    ITMS-91056A privacy manifest exists but does not parse against Apple's schemaInside a framework or resource bundle named in the error
    ITMS-91061A privacy manifest is missing from an SDK on Apple's commonly used SDKs listShould be present at the framework root, absent
    ITMS-91064Tracking information is missing or inconsistent in a privacy manifestInside a manifest declared NSPrivacyTracking true
    ITMS-91065The signature on a third-party SDK does not match the publisher of recordAt the framework level, signature mismatch

    If your error email starts with ITMS-91061 rather than ITMS-91056, the fix is different: you need to add a manifest, not repair one. If the email is ITMS-91065, you need a signed SDK build, not a manifest change. Read the prefix carefully before you start editing anything.

    What to watch out for

    A few patterns trip up teams the first time they hit ITMS-91056.

    Editing the root manifest does not affect SDK files. Many developers see Reachability in the path, open Xcode, and start adding API reasons to the root PrivacyInfo.xcprivacy. The next upload returns the same code. The validator runs per file. The repair has to happen at the path Apple named.

    A successful local build does not mean Apple will accept the upload. Privacy manifest validation runs in App Store Connect, not in Xcode's archive step. The first time you discover the failure is usually the processing email that arrives minutes after Transporter finishes.

    Builders that wrap native iOS, including FlutterFlow, React Native, and Expo prebuild flows, often pin pod versions through their templates. Updating the wrapper alone does not always update Reachability.framework. Inspect the resolved iOS lockfile after each prebuild.

    A myth worth rejecting: ITMS-91056 is not caused by missing entries in App Store Connect's data collection questionnaire. The questionnaire feeds the App Privacy section on the product page. It is checked at a different point in the pipeline and triggers different error codes. The OWASP MASTG guidance on iOS privacy treats the manifest and the App Privacy questionnaire as two separate controls, which matches how the upload pipeline checks them.

    Key takeaways

    • ITMS-91056 is a schema failure inside a framework's PrivacyInfo.xcprivacy. The path in the error email tells you which dependency owns the file.
    • Update the dependency first. A maintained release of Reachability.swift, or the wrapper that imports it, usually contains the corrected manifest.
    • Use a build phase strip only as a release-window patch. Apple still expects the required-reason API declarations to appear somewhere in the final IPA.
    • Read the error prefix carefully. ITMS-91056, 91061, 91064, and 91065 describe different failures and need different fixes.
    • Some teams run a pre-submission scan against the compiled IPA with a platform like PTKD.com (https://ptkd.com) to surface invalid privacy manifests, exposed secrets, and OWASP MASVS findings before Apple's validator catches the same issues under release pressure.
    • #itms-91056
    • #privacy manifest
    • #reachability framework
    • #app store connect
    • #ios
    • #third-party sdks
    • #owasp masvs

    Frequently asked questions

    Does ITMS-91056 mean my app's data collection is wrong?
    No, the code signals a format error, not a content error. Apple's validator parses the named PrivacyInfo.xcprivacy against the published schema and rejects anything malformed. The keys and values may be perfectly truthful about how the SDK uses data, but if the file has an unknown key, a wrong type, or a casing mismatch in an API reason string, you still receive ITMS-91056 regardless of correctness.
    Why does Apple flag Reachability.framework and not the SDK that imported it?
    The error names the framework that owns the bad PrivacyInfo.xcprivacy, not the parent package. Reachability.framework is often pulled in transitively, so the path in your email may be the first time you realize the library is in your build. Trace the dependency back through your Podfile.lock or Package.resolved to find the parent SDK responsible for the version pin.
    Can I edit the privacy manifest inside Pods/ to ship a fix today?
    You can, but the change is fragile. The next pod install rewrites the file, your CI build will not include the edit unless committed, and the framework signature can invalidate the manifest on rebuild. For one-off urgent submissions, a Run Script build phase that strips the file is more stable. For anything longer than one release, fork the library or wait for an upstream patch.
    Does updating Xcode fix ITMS-91056?
    No. The validation runs on Apple's servers when you upload an IPA, not in Xcode's local archive step. Newer Xcode versions help you catch privacy manifest warnings during development, but they do not modify the manifests inside third-party frameworks. The fix has to come from the framework author or from a build phase that touches the file before signing.
    How long does Apple take to surface ITMS-91056 after upload?
    In practice the processing email arrives within ten to twenty minutes of Transporter finishing the upload. The validator runs as part of App Store Connect processing, before TestFlight makes the build available. If you do not see an email within an hour, the build likely cleared validation and is moving toward TestFlight or App Review.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free