When running an iPhone or iPad app from Xcode, archiving it, or uploading it to App Store Connect, you may encounter an error or warning indicating that a purpose string is missing from Info.plist.
This usually happens when the app accesses privacy-sensitive hardware or user data such as the camera, microphone, photo library, location, contacts, or tracking APIs without providing the required usage-description key.
For example, camera access generally requires:
NSCameraUsageDescription
while photo-library access may require:
NSPhotoLibraryUsageDescription
A purpose string is the explanation that iOS displays to the user when requesting permission.
The correct fix is to identify the missing privacy key from the diagnostic and provide a short, accurate explanation of why your app needs that permission.
- What does “Missing purpose string in Info.plist” mean?
- Typical error message
- What is a purpose string?
- What to check first
- Common privacy usage-description keys
- Common causes
- 1. The usage-description key is missing
- 2. The key exists but the value is empty
- 3. The wrong privacy key was added
- 4. Camera and microphone are both used
- 5. Photo-library read and write access were confused
- 6. The wrong location authorization is requested
- 7. The wrong Info.plist is being edited
- 8. Debug and Release differ
- 9. An extension has separate bundle settings
- 10. A third-party SDK uses a protected API
- 11. Old privacy-sensitive code remains
- 12. App Tracking Transparency is used without a purpose string
- Solution 1: Add the key from Xcode’s Info tab
- Solution 2: Add the key directly to a physical Info.plist
- Solution 3: Add a microphone purpose string
- Solution 4: Add a photo-library purpose string
- Solution 5: Add an add-only photo-library purpose string
- Solution 6: Add a foreground location purpose string
- Solution 7: Request only the location authorization you actually need
- Solution 8: Use INFOPLIST_KEY settings with generated Info.plist
- Solution 9: Inspect privacy settings in Build Settings
- Solution 10: Inspect resolved Info.plist build settings
- Solution 11: Inspect the final Info.plist inside the app bundle
- Solution 12: Search your code for privacy-sensitive APIs
- Solution 13: Check third-party dependencies
- Solution 14: Remove unused protected-resource access
- Solution 15: Add a tracking usage description when using ATT
- How to write a good purpose string
- Purpose strings to avoid
- Localize purpose strings for multilingual apps
- If Debug works but Archive fails
- If the issue appears only during App Store Connect upload
- If a third-party SDK is responsible
- Request permission at an appropriate time
- If the user already denied permission
- Reset privacy permissions in Simulator
- Reset permissions for a macOS app during development
- Will Clean Build Folder fix it?
- Should you delete DerivedData?
- What you should avoid
- Fast troubleshooting checklist
- Summary
What does “Missing purpose string in Info.plist” mean?
Apple platforms require applications to explain why they need access to certain privacy-sensitive resources.
For example, an app may request camera permission with:
AVCaptureDevice.requestAccess( for: .video ) { granted in print(granted) }
The app also needs a camera usage description in its bundle configuration:
<key>NSCameraUsageDescription</key> <string>Camera access is used to take a profile photo.</string>
If the required description is missing, the application can terminate when it attempts to access the protected resource, or the issue may be detected during validation.
Important: The usage description is shown to real users. Do not treat it as placeholder metadata. Explain the actual feature that requires access.
Typical error message
This app has crashed because it attempted to access privacy-sensitive data without a usage description.
The app's Info.plist must contain an
NSCameraUsageDescription key with a string value
explaining to the user how the app uses this data.
The specific key changes depending on the protected resource.
What is a purpose string?
A purpose string is the message shown inside the system permission alert.
For example:
“MyApp” Would Like to Access the Camera
Camera access is used to take a profile photo.
The second sentence comes from your usage-description value.
What to check first
1. Read the key named in the error
If the diagnostic mentions:
NSCameraUsageDescription
the camera purpose string is missing.
Other common examples include:
NSMicrophoneUsageDescription NSPhotoLibraryUsageDescription NSLocationWhenInUseUsageDescription NSContactsUsageDescription
2. Identify which protected API is being used
The access may come from your own code or from a third-party dependency such as a camera scanner, analytics SDK, advertising SDK, or social framework.
3. Determine whether Xcode generates Info.plist
Check:
Target → Build Settings → Generate Info.plist File
The build-setting name is:
GENERATE_INFOPLIST_FILE
If it is YES, the privacy value may be supplied through target settings or an INFOPLIST_KEY_* build setting rather than a physical source plist.
Common privacy usage-description keys
NSCameraUsageDescription: camera accessNSMicrophoneUsageDescription: microphone accessNSPhotoLibraryUsageDescription: reading the photo libraryNSPhotoLibraryAddUsageDescription: add-only photo-library accessNSLocationWhenInUseUsageDescription: foreground location accessNSLocationAlwaysAndWhenInUseUsageDescription: location access that includes background useNSContactsUsageDescription: contactsNSLocalNetworkUsageDescription: local-network accessNSUserTrackingUsageDescription: App Tracking TransparencyNSSiriUsageDescription: Siri-related user data
Note: The exact key depends on the API, platform, and deployment target. Do not add a similarly named key by guesswork. Check the documentation for the API you actually use.
Common causes
1. The usage-description key is missing
The application uses the camera but does not contain:
NSCameraUsageDescription
2. The key exists but the value is empty
<key>NSCameraUsageDescription</key> <string></string>
Provide a real explanation instead.
3. The wrong privacy key was added
For example, add-only photo-library permission and photo-library read permission are not the same access mode.
4. Camera and microphone are both used
Video recording can involve both:
NSCameraUsageDescription NSMicrophoneUsageDescription
5. Photo-library read and write access were confused
Reading generally involves:
NSPhotoLibraryUsageDescription
while add-only access uses:
NSPhotoLibraryAddUsageDescription
6. The wrong location authorization is requested
If the app only needs location while it is active, a foreground authorization request may be more appropriate than requesting persistent background access.
7. The wrong Info.plist is being edited
A project with:
GENERATE_INFOPLIST_FILE = YES
may not use the physical plist you are modifying.
8. Debug and Release differ
The Debug configuration may contain the purpose string while Release does not, causing Archive-only failures.
9. An extension has separate bundle settings
Adding a purpose string to the main application does not automatically fix an extension that accesses the same protected resource.
10. A third-party SDK uses a protected API
The feature may exist inside a dependency even when your own code never calls the privacy API directly.
11. Old privacy-sensitive code remains
A feature may have been removed from the UI while its framework integration or execution path still remains.
12. App Tracking Transparency is used without a purpose string
If your app calls the App Tracking Transparency API, add:
NSUserTrackingUsageDescription
with an accurate explanation of why tracking permission is requested.
Solution 1: Add the key from Xcode’s Info tab
Open:
Project → Target → Info
Under Custom iOS Target Properties, add the appropriate privacy entry.
For camera access:
Privacy - Camera Usage Description
Example value:
Camera access is used to take a profile photo.
Solution 2: Add the key directly to a physical Info.plist
<key>NSCameraUsageDescription</key> <string>Camera access is used to take a profile photo.</string>
Solution 3: Add a microphone purpose string
<key>NSMicrophoneUsageDescription</key> <string>Microphone access is used to record audio with videos.</string>
Solution 4: Add a photo-library purpose string
<key>NSPhotoLibraryUsageDescription</key> <string>Photo access is used to select a profile image.</string>
Solution 5: Add an add-only photo-library purpose string
<key>NSPhotoLibraryAddUsageDescription</key> <string>Photo access is used to save images you create in the app.</string>
Solution 6: Add a foreground location purpose string
<key>NSLocationWhenInUseUsageDescription</key> <string>Your location is used to show nearby stores.</string>
Solution 7: Request only the location authorization you actually need
If location is only needed while the user is interacting with the app, avoid requesting persistent background access without a real product requirement.
Important: Request the least-privileged authorization that supports your feature.
Solution 8: Use INFOPLIST_KEY settings with generated Info.plist
If Xcode generates the plist, camera access can be configured with:
INFOPLIST_KEY_NSCameraUsageDescription
For example:
INFOPLIST_KEY_NSCameraUsageDescription = Camera access is used to take a profile photo.
Photo-library access can similarly use:
INFOPLIST_KEY_NSPhotoLibraryUsageDescription
Solution 9: Inspect privacy settings in Build Settings
Search for entries such as:
Privacy - Camera Usage Description
and confirm that the Release configuration contains the intended value.
Solution 10: Inspect resolved Info.plist build settings
xcodebuild \ -project MyApp.xcodeproj \ -scheme MyApp \ -showBuildSettings | grep INFOPLIST_KEY
For Release:
xcodebuild \ -project MyApp.xcodeproj \ -scheme MyApp \ -configuration Release \ -showBuildSettings | grep INFOPLIST_KEY
Solution 11: Inspect the final Info.plist inside the app bundle
plutil -p /path/to/MyApp.app/Info.plist
To check one key:
plutil -p /path/to/MyApp.app/Info.plist | grep NSCameraUsageDescription
This confirms whether the key actually reached the distributed build.
Solution 12: Search your code for privacy-sensitive APIs
Camera:
grep -R "AVCaptureDevice" .
Location:
grep -R "CLLocationManager" .
App Tracking Transparency:
grep -R "ATTrackingManager" .
Solution 13: Check third-party dependencies
A Swift package, CocoaPod, or binary framework may use camera, location, tracking, or another protected API internally.
If that functionality is optional, check whether the SDK allows you to disable it.
Solution 14: Remove unused protected-resource access
If your product does not need the feature anymore, removing the API access may be better than adding a misleading purpose string.
Solution 15: Add a tracking usage description when using ATT
<key>NSUserTrackingUsageDescription</key> <string>Permission is requested to measure advertising performance and provide more relevant ads.</string>
Note: Adding this text does not replace the requirements of App Tracking Transparency or App Store privacy policies.
How to write a good purpose string
A weak description:
Camera access is required.
is less useful than:
Camera access is used to take a profile photo.
For location:
Your location is used to show nearby stores.
For microphone access:
Microphone access is used to record audio with videos.
Purpose strings to avoid
- Text that only repeats the permission name
- “Because the app needs it”
- A use case the app does not actually perform
- Language that pressures the user into granting permission
- Overly technical implementation details
Localize purpose strings for multilingual apps
For a localized app, permission descriptions can also be localized.
A common approach is:
InfoPlist.strings
English:
"NSCameraUsageDescription" = "Camera access is used to take a profile photo.";
Japanese:
"NSCameraUsageDescription" = "プロフィール写真を撮影するためにカメラを使用します。";
If Debug works but Archive fails
Check:
- The Release configuration
- Release .xcconfig files
- The target being archived
- Extension Info.plist settings
- The final Info.plist inside the archive
If the issue appears only during App Store Connect upload
The protected API may exist in the binary even if your local test path never triggered it.
Check:
- Whether the protected API is actually needed
- Whether the matching purpose string exists
- Whether a dependency uses the API
- Whether the key exists in the archived Info.plist
If a third-party SDK is responsible
Review the SDK’s current documentation.
Some SDKs include optional modules that reference privacy-sensitive APIs. Disabling unused modules or updating the SDK may remove unnecessary permission requirements.
Request permission at an appropriate time
After configuring the purpose string, request permission when the user reaches the feature that needs it.
Camera example:
AVCaptureDevice.requestAccess( for: .video ) { granted in if granted { print("Camera permission granted") } else { print("Camera permission denied") } }
Requesting a permission in context usually makes the purpose clearer than presenting several privacy prompts immediately at app launch.
If the user already denied permission
Changing the purpose string does not necessarily cause the system prompt to appear again for an already-decided permission.
On a device, the user can review permissions under Settings and Privacy & Security.
During development, deleting and reinstalling the app may also reset some permission state.
Reset privacy permissions in Simulator
xcrun simctl privacy booted reset all
You can inspect simctl privacy help for supported service-specific commands.
Reset permissions for a macOS app during development
Depending on the permission, macOS developers can use commands such as:
tccutil reset All com.example.MyApp
Note: Permission-reset commands are development tools. Your shipping app cannot silently reset a user’s privacy choices.
Will Clean Build Folder fix it?
Not if the required usage-description key is genuinely missing.
You can run:
Product → Clean Build Folder
after correcting the configuration, but the missing purpose string itself must still be added.
Should you delete DerivedData?
Usually not as the first troubleshooting step.
If you have already corrected the privacy configuration and suspect stale artifacts, you can try:
rm -rf ~/Library/Developer/Xcode/DerivedData/*
as a secondary measure.
What you should avoid
Do not add every possible privacy key simply to make validation errors disappear.
Only request access that your app actually needs, and make every purpose string accurately describe the corresponding feature.
A generic description such as:
This permission is required.
does not clearly explain the benefit to the user.
Fast troubleshooting checklist
- Read the missing usage-description key from the error.
- Confirm that the app actually uses the protected API.
- Add the matching purpose string.
- Do not leave the value empty.
- Explain the real user-facing reason for access.
- Check whether both camera and microphone permissions are required.
- Distinguish photo-library read access from add-only access.
- Check the type of location authorization requested.
- Check GENERATE_INFOPLIST_FILE.
- For generated plists, inspect INFOPLIST_KEY_* settings.
- Compare Debug and Release.
- Check extension targets.
- Inspect third-party SDKs.
- Verify the key in the archived Info.plist with plutil.
- Localize purpose strings in multilingual apps.
Summary
Xcode’s “Missing purpose string in Info.plist” problem occurs when an app accesses privacy-sensitive data or hardware without providing the required usage-description value.
Camera access commonly requires NSCameraUsageDescription, microphone access requires NSMicrophoneUsageDescription, and photo-library access can require NSPhotoLibraryUsageDescription or NSPhotoLibraryAddUsageDescription, depending on how the library is used.
The purpose string should tell the user why your feature needs the requested access, not simply repeat the name of the permission.
For targets that generate Info.plist, privacy descriptions can be supplied through build settings such as INFOPLIST_KEY_NSCameraUsageDescription.
If Debug succeeds but Archive fails, inspect the Release configuration. If the problem appears only during upload, inspect dependencies and the actual Info.plist inside the archived application.
Cleaning build artifacts is secondary. The real fix is to ensure that every privacy-sensitive API your app uses has the correct, meaningful purpose string in the final built bundle.
