NSURLSession
NSURLConnection
iOS 9
HTTP load error
iOS development

NSURLSession/NSURLConnection HTTP load failed on iOS 9

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

On iOS 9, a plain HTTP request that used to work suddenly started failing in many apps because App Transport Security, or ATS, became the default network security policy. When NSURLSession or NSURLConnection reports an HTTP load failure, the usual cause is that the app is trying to talk to an insecure endpoint or to a server that does not meet ATS requirements.

What ATS Changed

ATS requires apps to prefer secure transport. In practice, that means:

  • use https instead of http
  • use a modern TLS configuration
  • present a certificate chain the system trusts

So code that looks harmless can fail if the URL is plain HTTP.

swift
1import Foundation
2
3let url = URL(string: "http://example.com/data.json")!
4let task = URLSession.shared.dataTask(with: url) { data, response, error in
5    print(data as Any, response as Any, error as Any)
6}
7task.resume()

On iOS 9, this often fails unless the app or domain has an ATS exception.

Preferred Fix: Serve the Resource Over HTTPS

The best solution is almost always to fix the server, not the app config. If the endpoint supports HTTPS with valid TLS settings, switch the URL and remove any need for exceptions.

swift
let url = URL(string: "https://example.com/data.json")!

This keeps the app aligned with the platform security model and avoids later maintenance work.

Add a Domain-Specific Exception Only When Necessary

If you must talk to a legacy server temporarily, add a narrow exception in Info.plist instead of disabling ATS for the whole app.

xml
1<key>NSAppTransportSecurity</key>
2<dict>
3    <key>NSExceptionDomains</key>
4    <dict>
5        <key>example.com</key>
6        <dict>
7            <key>NSIncludesSubdomains</key>
8            <true/>
9            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
10            <true/>
11        </dict>
12    </dict>
13</dict>

This is still a compromise. The real fix is to migrate the endpoint to HTTPS.

Avoid Global ATS Disable Unless There Is No Alternative

You can disable ATS broadly, but that should be a last resort because it weakens the entire app.

xml
1<key>NSAppTransportSecurity</key>
2<dict>
3    <key>NSAllowsArbitraryLoads</key>
4    <true/>
5</dict>

This often gets copied from old forum posts because it makes the error disappear quickly. The problem is that it removes the security protection far beyond the one failing endpoint.

Debug the Actual Server Behavior

Sometimes the URL already uses HTTPS and still fails. In that case, the issue may be:

  • an outdated TLS version
  • an invalid certificate chain
  • a hostname mismatch
  • redirects from HTTPS back to HTTP

Check the final network path instead of assuming the visible URL tells the full story. A server that redirects secure requests to plain HTTP will still violate ATS.

NSURLConnection Versus URLSession

NSURLConnection and NSURLSession are both subject to ATS. Changing the client API alone does not solve the problem.

So if this fails:

objective-c
1NSURL *url = [NSURL URLWithString:@"http://example.com/data.json"];
2NSURLRequest *request = [NSURLRequest requestWithURL:url];
3[NSURLConnection sendAsynchronousRequest:request
4                                   queue:[NSOperationQueue mainQueue]
5                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
6    NSLog(@"%@", error);
7}];

moving the same HTTP URL to NSURLSession will not bypass ATS. The transport policy is the same.

Common Pitfalls

The biggest mistake is disabling ATS globally to unblock one legacy endpoint. That creates a much larger security exception than most apps actually need.

Another mistake is adding an exception for the visible domain while the real failure happens on a redirected host, a CDN domain, or an API subdomain.

Developers also often test only in the simulator and miss production-like certificate issues that appear on real devices or with real network paths.

Finally, do not assume that because the URL starts with https, the server satisfies ATS. Certificate and TLS details still matter.

Summary

  • On iOS 9, ATS blocks insecure or weakly secured network requests by default.
  • The preferred fix is to serve the resource over properly configured HTTPS.
  • If a temporary exception is unavoidable, scope it to the specific domain instead of the whole app.
  • 'NSURLSession and NSURLConnection both obey ATS, so changing APIs alone does not fix the issue.'
  • Inspect redirects, certificates, and TLS behavior when HTTPS still appears to fail.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.