Privacy

    How do I fix ITMS-91053 for the file timestamp API?

    App Store Connect rejection email referencing ITMS-91053 and NSPrivacyAccessedAPICategoryFileTimestamp

    You uploaded a build to App Store Connect, the processing email arrived a few minutes later, and the body referenced ITMS-91053 with NSPrivacyAccessedAPICategoryFileTimestamp flagged. The app runs in the simulator, the previous TestFlight build cleared, but today the upload is held with the status Invalid Binary. The question is what that one line in the email actually means, which call inside the binary is responsible, and the smallest change that lets the next upload process cleanly.

    Short answer

    App Store Connect rejects builds that read file creation, modification, or access timestamps without declaring those calls in a PrivacyInfo.xcprivacy file. The fix is a privacy manifest containing NSPrivacyAccessedAPICategoryFileTimestamp paired with an approved reason code: C617.1 for files in the app container, 3B52.1 for user-granted paths, DDA9.1 for timestamps shown to the user, or 0A2A.1 for third-party SDK wrappers. Apple has enforced the rule for new submissions since 1 May 2024, per the Apple Developer privacy manifest documentation.

    What you should know

    Why does App Store Connect return ITMS-91053 for file timestamp APIs?

    The short answer is that Apple now scans every uploaded binary for symbols associated with a defined set of required reason APIs, and it refuses to process a build that references one of those symbols without a matching declaration in a privacy manifest. The file timestamp group covers NSURL resource keys like NSURLCreationDateKey, NSURLContentModificationDateKey, and NSURLContentAccessDateKey, plus NSFileManager methods like attributesOfItemAtPath, plus the BSD calls stat, fstat, lstat, fstatat, and the getattrlist family.

    The scan does not read your Swift or Objective-C source. It reads the compiled Mach-O. A project that builds and runs without complaint can still fail on upload because a linked framework calls one of those symbols and the symbol survived stripping. Apple's TN3183 technote describes the rule as an audit of API usage, not a behavioural check, which is why the diagnostic appears during processing rather than at runtime.

    Which reason code should I pick for the file timestamp category?

    Apple publishes four approved reasons under NSPrivacyAccessedAPICategoryFileTimestamp. Each one matches a different real-world purpose, and a single manifest entry can list more than one when the app legitimately spans cases.

    The most common reason is C617.1. It covers reading timestamps, size, or other metadata for files inside the app container, the app group container, or the app's CloudKit container. Cache eviction logic, "files older than seven days" cleanup, and resumable downloads usually sit here.

    3B52.1 covers files or directories that the user explicitly granted access to, typically through UIDocumentPickerViewController or a security-scoped bookmark. Editor apps, file viewers, and any tool that takes a user-selected path use this code.

    DDA9.1 is for cases where the timestamp is displayed in the interface to the person using the device, for example a "last modified" label in a file list. If the read exists only to render UI, this is the right code.

    0A2A.1 is restricted to third-party SDKs that wrap a file timestamp API behind a function the host app calls. The SDK ships this declaration in its own manifest; an app developer does not use 0A2A.1 for first-party code.

    Cases reported on the Apple Developer forum thread on stat() show that submitting C617.1 when 3B52.1 would have been more accurate does not block the upload. Apple does not police the alignment between the description and the call at ingestion. The audit only checks that one approved reason is present for the category. Picking the reason that genuinely matches the call is still the safer practice, because a later human review pass can ask about it.

    How do I add the entry to PrivacyInfo.xcprivacy?

    The file goes into the bundle of the target that calls the API. For a plain iOS app with no embedded frameworks, that is the app target, and PrivacyInfo.xcprivacy sits at the root of the .app folder. Add it via File, New, File from Template, App Privacy under the Resource section. Xcode generates an empty plist and registers it with the current target.

    The one step developers miss is target membership. Open the File Inspector on the new manifest, scroll to Target Membership, and confirm the app target box is ticked. A manifest in the project navigator but outside target membership never reaches the .app bundle, and ITMS-91053 returns on the next upload.

    The smallest valid entry for a file-timestamp-only fix is one dictionary inside the NSPrivacyAccessedAPITypes array, with NSPrivacyAccessedAPIType set to NSPrivacyAccessedAPICategoryFileTimestamp and NSPrivacyAccessedAPITypeReasons set to an array containing one or more reason strings.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
      <key>NSPrivacyAccessedAPITypes</key>
      <array>
        <dict>
          <key>NSPrivacyAccessedAPIType</key>
          <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
          <key>NSPrivacyAccessedAPITypeReasons</key>
          <array>
            <string>C617.1</string>
          </array>
        </dict>
      </array>
    </dict>
    </plist>
    

    If the same target also reads disk space, user defaults, or system boot time, those go in as sibling dictionaries inside the same NSPrivacyAccessedAPITypes array. After editing the plist, archive the project, right-click the .ipa in Finder and Show Package Contents, and confirm PrivacyInfo.xcprivacy sits at the top level of the .app folder before the next upload.

    How do I find which framework calls a file timestamp API?

    A build that compiles fine but fails on upload usually carries the call inside a CocoaPods, Swift Package Manager, or vendored .xcframework dependency. There are three reliable paths to identify the responsible SDK.

    The first is symbol grep. After archiving, open the .ipa, navigate to Payload/.app/Frameworks, and run nm -u on each binary to list referenced symbols. A match on stat, fstat, getattrlist, attributesOfItemAtPath, or any NSURL resource key with Date in the name narrows the candidate list quickly. TN3183 recommends this approach for finding the responsible SDK.

    The second is the SDK's own changelog. Most major vendors began shipping privacy manifests in spring 2024. Firebase, Google Mobile Ads, AppsFlyer, Adjust, Sentry, Branch, and Lottie all published manifest-bearing releases by mid-2024. If the Podfile or Package.resolved is pinned to a pre-April 2024 version, bumping to a current release usually clears the rejection without manual plist work.

    The third is process of elimination. Comment out a suspect SDK initialization, archive, and upload to a separate test app record. If the rejection disappears, that SDK is the source. The approach is slow but useful for closed-source dependencies without a public changelog.

    Which file timestamp APIs trigger the scan?

    The table below collects the most common entry points that App Store Connect's scanner flags under NSPrivacyAccessedAPICategoryFileTimestamp, based on Apple's published list.

    API or symbolFrameworkTypical caller
    NSURLContentModificationDateKeyFoundation (URLResourceKey)Cache freshness, sync logic
    NSURLCreationDateKeyFoundationSort by date in a file list
    NSURLContentAccessDateKeyFoundationLRU eviction policies
    attributesOfItemAtPath, attributesOfFileSystemForPathNSFileManagerOlder Objective-C code paths
    stat, fstat, lstat, fstatatBSD libcC and C++ libraries, analytics SDKs
    getattrlist, getattrlistat, fgetattrlistBSD libcLower-level performance code

    Apple groups every entry above under a single category, so one reason code on a single dictionary entry covers any combination of these calls. There is no separate code per symbol.

    What to watch out for

    Key takeaways

    Frequently asked questions

    Is ITMS-91053 a hard rejection or just a warning?
    Since 1 May 2024 it is a hard rejection for new App Store submissions and TestFlight builds, per Apple's published enforcement timeline. Before that date the same message arrived as informational email and the build still processed. Today the build is held in App Store Connect with the status Invalid Binary, and the developer cannot ship until the manifest is corrected and a new build is uploaded with a higher build number.
    Which reason code do I pick for file timestamps?
    Pick the reason that matches the actual call. C617.1 covers files in the app container, app group, or CloudKit container. 3B52.1 covers files the user picked through a document picker or security-scoped bookmark. DDA9.1 is for timestamps displayed in the user interface. 0A2A.1 is reserved for third-party SDKs that wrap file timestamp APIs. App Store Connect accepts any of the four at ingestion.
    Why does ITMS-91053 still appear after I added the manifest?
    Three common reasons. First, the PrivacyInfo.xcprivacy file is not part of the target that ships; check Target Membership in the File Inspector. Second, the manifest is in your app but the file timestamp call lives inside a third-party framework that needs its own manifest. Third, the build number was not incremented, so App Store Connect kept the old binary in processing instead of ingesting the new one.
    Do I need a manifest if I only use Apple frameworks?
    Yes if your app or any first-party code calls one of the file timestamp APIs listed in Apple's Required Reason API table, such as NSURLContentModificationDateKey, attributesOfItemAtPath, or stat. The required reason rule applies to your own code, not only to vendor SDKs. The manifest can sit at the root of the app target with a single NSPrivacyAccessedAPICategoryFileTimestamp entry and one reason code such as C617.1.
    Will adding a privacy manifest change anything users see?
    No. The privacy manifest is metadata read by App Store Connect during ingestion and surfaced in the Privacy Nutrition Label that Apple shows on the App Store listing. Runtime behaviour of the app does not change, no new permission prompt appears, and existing users see no difference. The manifest only affects what Apple's automated review pipeline accepts and what the public listing displays for privacy disclosures.

    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