ATS Exceptions: Configure Without Review Issues
23 Feb 2026 · 6 min read · Erik van Kammen
App Transport Security has been part of iOS since iOS 9. By now, every iOS developer knows the basics: use HTTPS, don't disable ATS globally, and you'll be fine.
Except the edge cases are where teams get into trouble.
Legacy APIs, local network communication, media streaming, third-party SDKs with their own networking requirements. These all create situations where you need ATS exceptions. Configuring them incorrectly can lead to review delays or outright rejection.
Here's how to configure ATS exceptions correctly and what Apple actually checks.
ATS requires that all network connections from your app use HTTPS with modern TLS settings.
Specifically:
When your app makes a connection that doesn't meet these requirements, ATS blocks it by default.
Not all legitimate network communication meets ATS requirements. Common cases:
Apps that communicate with local hardware (printers, IoT devices, media servers) often use HTTP on the local network. These devices don't have TLS certificates.
Some third-party APIs or partner integrations still serve content over HTTP or use outdated TLS configurations. You can't always control the server you're connecting to.
Some media content delivery networks serve assets over HTTP or require specific TLS configurations that don't match ATS defaults. Apple provides NSAllowsArbitraryLoadsForMedia specifically for this case, which allows AV Foundation to load media without ATS restrictions while keeping the rest of your networking locked down.
Apps that display arbitrary web content (in-app browsers, web views) may encounter pages that don't meet ATS requirements.
ATS exceptions are declared in your Info.plist under the NSAppTransportSecurity dictionary.
| Exception Type | Scope | Review Risk | Typical Use Case |
|---|---|---|---|
Per-domain (NSExceptionDomains) |
Single domain | Low | Legacy API servers |
Local networking (NSAllowsLocalNetworking) |
localhost/LAN | Low | IoT, dev tools |
Arbitrary loads for media (NSAllowsArbitraryLoadsForMedia) |
AV content | Medium | Streaming, legacy CDN |
Arbitrary loads in web content (NSAllowsArbitraryLoadsInWebContent) |
WKWebView | Medium | Browser, web views |
Arbitrary loads (NSAllowsArbitraryLoads) |
Global | High | Usually triggers review scrutiny |
The safest approach. Specify exactly which domains need exceptions and what you're allowing.
<!-- Info.plist: per-domain ATS exception for legacy-api.example.com -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>legacy-api.example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
This allows insecure connections to one specific domain while keeping ATS enforced everywhere else.
Available exception keys per domain:
NSExceptionAllowsInsecureHTTPLoads: allows HTTPNSExceptionMinimumTLSVersion: lowers the minimum TLS version (TLS 1.0 and 1.1 are deprecated and likely to trigger rejection)NSExceptionRequiresForwardSecrecy: disables the forward secrecy requirementNSIncludesSubdomains: applies the exception to all subdomainsFor apps that need local network access without TLS:
<!-- Info.plist: allow local network connections (IoT, LAN devices) -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
This allows connections to local IP addresses and .local domains without affecting internet-facing connections.
<!-- Info.plist: disable ATS globally (requires App Review justification) -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
This disables ATS entirely. Apple requires justification for this during review.
Valid use cases exist: in-app browsers that load user-provided URLs, content aggregators, or development builds.
But using this in production requires you to explain why in the review notes. If Apple isn't convinced, they'll ask you to scope it down.
Apple's review process includes verification of ATS configuration. Here's what matters:
If you use NSAllowsArbitraryLoads, expect Apple to ask why. "Our API doesn't support HTTPS" isn't a good answer in 2026. "We display user-provided web content in a web view" is more reasonable.
Reviewers may question exceptions that don't appear consistent with your app's stated purpose. Keeping exceptions tightly scoped to actual needs reduces the chance of review questions.
Apple prefers narrow exceptions. Per-domain exceptions for specific hosts are accepted more readily than blanket disabling.
If your app uses WKWebView to display arbitrary web content, Apple expects NSAllowsArbitraryLoadsInWebContent rather than NSAllowsArbitraryLoads. This allows web views to load any content while keeping ATS enforced for your app's own network calls.
<!-- Info.plist: allow arbitrary loads in WKWebView only -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
If you know exactly which domains need exceptions, specify them. Using arbitrary loads because it's easier invites unnecessary review scrutiny.
You've added an exception for api.example.com but your API also serves from cdn.api.example.com. Without NSIncludesSubdomains, the subdomain isn't covered.
Third-party SDKs make network calls too. If an SDK connects to a server that doesn't meet ATS requirements, you need to account for that in your exceptions.
This is tricky because SDK networking behavior isn't always documented. Binary analysis can help surface which domains and protocols are used.
Debug builds sometimes behave differently from release builds. Test your ATS configuration in the same build configuration you'll submit.
NSAllowsArbitraryLoads is convenient during development. Shipping it to production is a different story. Add a build-phase check or CI step that flags overly broad ATS exceptions in release builds.
This is where things get complicated for compliance.
An SDK you embed might need specific ATS exceptions to function. The SDK documentation might tell you this. Or it might not.
Typical issues:
In each case, you need the right exception in your Info.plist. If the SDK doesn't document its requirements, you'll find out the hard way when calls fail silently or the SDK logs errors.
Approach:
ATS configuration is part of your Info.plist, which lives in source control. But the effective configuration in the compiled binary is what matters. Binary analysis catches discrepancies between source and artifact.
Build variables, target-specific overrides, and plist preprocessing can all change the final values. Verify the ATS configuration in the compiled IPA, not just in the source file.
A practical CI check:
AppCompliance checks ATS configuration as part of its iOS binary scan, alongside privacy manifest validation and other compliance signals, including detection of globally disabled ATS via NSAllowsArbitraryLoads. No tool can guarantee that Apple will approve your ATS configuration, but catching a globally disabled ATS before submission saves back-and-forth during review.
Everything technical in this post is checkable from the build itself, and that is exactly what AppCompliance does: upload an iOS or Android build, and minutes later you have every issue that would get it rejected, with the exact fix next to it.
One email when we open the doors. No spam, just the launch.