You upload a build to App Store Connect, the processing email arrives, and inside it a warning labelled ITMS-91053 names the DiskSpace API category and refuses to let the archive go further. The binary is otherwise fine. The privacy manifest is the part that is failing the check, and the fix is mechanical once you know which call triggered it.
Short answer
ITMS-91053 fires when your iOS archive references a required reason API in the DiskSpace category (such as volumeAvailableCapacityKey, volumeAvailableCapacityForImportantUsageKey, or NSFileSystemFreeSize) without an approved entry in PrivacyInfo.xcprivacy. The fix is to add an NSPrivacyAccessedAPICategoryDiskSpace block with one of the published reason codes (most often 85F4.1 or E174.1) at the app target if you call the API directly, or at the SDK that owns the call if a dependency does. Apple stopped accepting builds without these entries from 1 May 2024.
What you should know
- The category, not the function, drives the check. Apple groups specific calls under
NSPrivacyAccessedAPICategoryDiskSpace, and the manifest declares the category plus a reason code, not the call itself. - There are four approved disk space reason codes.
85F4.1,E174.1,7D9E.1, andB728.1cover the documented use cases. Picking the wrong one is a policy issue, but only the presence of a valid code clears the upload check. - First-party and third-party code are scanned together. A clean app target still triggers ITMS-91053 if a linked framework reaches the API and ships without its own manifest.
- The 1 May 2024 deadline is hard at upload time. App Store Connect emits the warning and refuses the build, so this is not a guideline that surfaces in App Review, it is a gate before the submission ever reaches a reviewer.
- The fix lives in one file. A single
PrivacyInfo.xcprivacyresource at the app target carries every category declaration, and it has to be a member of the app target, not just present in the project.
Why does App Store Connect flag disk space APIs at all?
The short answer is that Apple treats a small set of system APIs as susceptible to fingerprinting, and disk space is one of them. According to Apple's Required Reason API documentation, the categories cover system calls whose return values can identify a device or a user when combined with other signals. Free storage in bytes is one such signal: paired with locale, timezone, and a few other read-only values, it narrows a population of devices quickly.
The mechanism is that the App Store Connect upload pipeline scans the archive for symbol references to the listed APIs, then cross-checks each category it finds against the merged PrivacyInfo.xcprivacy from the app and every embedded framework. A category that shows up in the scan and is missing from the manifest produces ITMS-91053.
The consequence is that the developer carries the declaration burden, not Apple's reviewers. The check is automated, deterministic, and runs every upload. The warning is also factual: it tells you which category is missing, and the symbol scan that produced it is the same one Apple has run since 1 May 2024 according to the Apple Developer Newsroom post on Required Reason API requirements.
The limit is that the upload pipeline does not tell you which file or which framework triggered the scan. That work is on the developer.
Which calls actually trigger the warning?
The short answer is the small set of APIs Apple lists explicitly under the DiskSpace category. According to the same Required Reason API page, the disk space category covers volumeAvailableCapacityKey, volumeAvailableCapacityForImportantUsageKey, volumeAvailableCapacityForOpportunisticUsageKey, volumeTotalCapacityKey, systemFreeSize, systemSize, and the Objective-C and Foundation equivalents such as NSFileSystemFreeSize and NSFileSystemSize.
The practical pattern is that any code path asking the OS how much space is left, how much space the volume has in total, or how much of that space is currently used falls into this category. Calls that operate on URLResourceValues or that read [[NSFileManager defaultManager] attributesOfFileSystemForPath:] all surface the same category in the scan.
A frequent source of confusion is Swift wrappers. URL.resourceValues(forKeys:) with .volumeAvailableCapacityKey is the modern entry point, and it still maps to the same underlying symbols in the linked binary. Wrapping the call in a custom helper does not remove the symbol; the linker keeps it, and the scan finds it.
The limit is third-party code. A logger that records device telemetry, a crash reporter that captures free disk space at the time of a crash, an analytics SDK that adds storage info to event payloads, all show up as DiskSpace API users in the scan, and all are common origins of an unexpected ITMS-91053 on an app whose own source has no disk space calls.
How do I add the disk space entry to PrivacyInfo.xcprivacy?
The short answer is one property list file with one extra dictionary inside NSPrivacyAccessedAPITypes. According to Apple's TN3183 technote, the privacy manifest is a property list named exactly PrivacyInfo.xcprivacy, placed at the top level of the app or framework bundle.
The minimum entry for the disk space category looks like this:
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>85F4.1</string>
</array>
</dict>
The steps are uncomplicated. In Xcode, choose File, New, File from Template, then App Privacy File under the Resource section. Name the file PrivacyInfo.xcprivacy, place it at the project root, and confirm that target membership includes the app target. Open the file in the Xcode property list editor or as Source. Add the dictionary above under the NSPrivacyAccessedAPITypes array, picking the reason code that matches the call site. Archive, upload, and the ITMS-91053 warning for DiskSpace will be gone if the entry is valid and the file is in the archive.
The four reason codes are scoped narrowly. The right code depends on what the call site actually does.
| Reason code | When it applies |
|---|---|
85F4.1 | Showing free or total disk space to the user inside the app interface. Derived data may not leave the device. |
E174.1 | Checking that enough space is available before writing a file the user requested. |
7D9E.1 | Related storage availability check that does not match E174.1 exactly, often used by media or download flows. |
B728.1 | Health research apps detecting low storage that affects participant data collection. |
The limit is honesty. The presence of a valid code clears the upload, but a code declared without a corresponding behaviour in the app is still a privacy policy violation and can be cited in App Review or in a later Data Safety audit on Google Play if the same codebase ships to both stores.
What if the call comes from a third-party SDK?
The short answer is that the SDK is supposed to ship its own PrivacyInfo.xcprivacy, and Apple maintains a list of commonly-used third-party SDKs that are required to ship one. According to Apple's published list of commonly-used SDKs, names such as Firebase, Alamofire, FirebaseCrashlytics, FBSDKCoreKit, GoogleUtilities, SDWebImage, OpenSSL, and many of the Flutter and React Native bridges are on the list. SDKs on that list also have to be signed.
The mechanism is that Xcode merges all PrivacyInfo.xcprivacy files from the linked frameworks into a single manifest at build time. The App Store Connect upload scan sees the merged result. If the SDK ships a clean manifest with its own DiskSpace entry, your app target does not need to declare on its behalf.
In practice, three patterns show up. The first is an SDK that has updated and ships the manifest; updating the version usually clears the warning with no extra work on your side. The second is an SDK that has not updated; the choice is between waiting, replacing the dependency, or adding the entry to your app target as a workaround. The third is an SDK that does ship a manifest but with a stale reason code; the merged file is then technically invalid, and the warning returns.
For builders shipping AI-generated or no-code wrappers (a FlutterFlow build with three or four community plugins, an Expo project with native modules from npm, a React Native app stitched together from older libraries), this is the most common reason ITMS-91053 surfaces despite a clean app target. A binary-level scan against the archived .ipa is the fastest way to find which framework owns the symbol. PTKD.com (https://ptkd.com) is one of the platforms that runs this kind of pre-submission scan on the compiled build and lists each required reason API category by the framework that triggered it, which shortens the chase considerably for AI-coded and no-code apps.
The limit is that you do not own the SDK. Declaring on behalf of a dependency clears the upload, but if that dependency starts collecting disk space data in a future version, your declaration may no longer match reality, and the obligation to keep the manifest accurate sits with the app developer.
How do I confirm the fix before resubmitting?
The short answer is to verify the manifest is in the archive, well-formed, and contains the expected entry, before you upload again. App Store Connect will tell you ITMS-91053 is gone only after another upload, which is slow.
The useful local checks are short. Archive the build through Product, Archive, then in the Organizer right-click the archive and choose Show in Finder. Right-click the .xcarchive, Show Package Contents, navigate to Products/Applications/YourApp.app/, and confirm PrivacyInfo.xcprivacy is sitting next to Info.plist. Run plutil -lint PrivacyInfo.xcprivacy to confirm the property list parses. Run plutil -p PrivacyInfo.xcprivacy to print the resolved structure and check that NSPrivacyAccessedAPICategoryDiskSpace is present with one of the four codes.
For a deeper view, the xcrun strings command on the unsigned binary inside the bundle, filtered for volumeAvailableCapacity or FileSystemFreeSize, gives a quick read on whether the symbol you declared for is genuinely present. If the symbol is gone (because the SDK that needed it was removed), the entry can be removed too, since OWASP MASVS guidance on platform-specific privacy controls recommends declaring access only for code actually shipped.
The limit is that a local scan does not replicate the App Store Connect pipeline byte-for-byte. The standard practice is to keep an internal TestFlight track open and use it as the canary for upload-time warnings.
What to watch out for
A few patterns surface repeatedly on the Apple Developer Forums thread for required reason API current status and in vendor reports such as the NowSecure mobile app security analyses.
First, PrivacyInfo.xcprivacy is sometimes added to the project but not to the target membership. The build succeeds, the archive does not contain the file, and the warning returns on upload. Always confirm target membership in the File Inspector.
Second, the wrong reason code is treated as no reason code at all. The string has to match one of the four exactly, including the case and the trailing .1. Typos here are silent; the file parses, the scan flags it.
Third, the warning is sometimes blamed on the wrong category. ITMS-91053 covers all required reason API categories (UserDefaults, FileTimestamp, SystemBootTime, ActiveKeyboards, DiskSpace), and the email text names which one applies. Read the email carefully.
Fourth, watch the SDK supply chain. A dependency that ships a clean manifest today can introduce a new category in a future version. Each major SDK upgrade is a fresh manifest review, even when the rest of the codebase has not changed.
Fifth, the manifest is not a substitute for the privacy nutrition label. App Store Connect asks separately about the data your app collects, and the privacy manifest answers a narrower question about which sensitive APIs are reached. Both are checked, in different gates.
Key takeaways
- ITMS-91053 for DiskSpace is a deterministic upload-time gate. Add a single
NSPrivacyAccessedAPICategoryDiskSpaceentry with one of the four published reason codes, confirm the manifest is in the archive, and resubmit. - Most of the work is identifying which framework triggered the scan, not editing the manifest itself.
- Keep the
PrivacyInfo.xcprivacyhonest. The presence check is automated; the truthfulness check happens later, in App Review or in a Data Safety audit. - For builders shipping AI-generated or no-code apps with many native dependencies, running a pre-submission scan against the archived
.ipa, including from external services such as PTKD.com (https://ptkd.com), tends to surface the missing category and its owning framework faster than a re-archive cycle through App Store Connect. - Treat each SDK upgrade as a fresh privacy manifest review, since required reason API usage can change between versions without any visible change to your own source code.




