Phones and operating systems
NSURLErrorDomain -1200: "An SSL error has occurred" on iOS
NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made."NSURLErrorDomain Code=-1200 means an app on iOS or macOS could not establish a secure connection: the TLS handshake failed. Apple's URL loading system enforces App Transport Security (ATS), so servers that are fine for some browsers can still fail inside apps. The fix is almost always on the server, occasionally in the app's ATS settings.
Is it the site or your device?
Almost always the server: it fails App Transport Security requirements. Check the API or website host with the SSL checker:
curl ssl.sh/example.com
If the server lacks TLS 1.2, uses weak ciphers or has an incomplete chain, it fails for every user. If the server passes and only some users fail, look at their networks and installed profiles. On a Mac, run Apple's ATS diagnostics against the exact URL the app uses:
nscurl --ats-diagnostics --verbose https://api.example.com
Causes
1. Server does not meet ATS requirements
ATS needs TLS 1.2 or newer and forward-secret (ECDHE) cipher suites. Servers offering only TLS 1.0/1.1 or RSA key exchange fail with -1200.
2. Certificate does not meet Apple's rules
SHA-1 signatures, RSA keys under 2048 bits, missing SAN entries or excessive validity periods break ATS or Apple's trust evaluation. Depending on where it fails, you see -1200 or -1202.
3. Incomplete chain or private CA
A missing intermediate or a private CA without the root installed usually produces -1202, but some handshake paths report -1200. Fix the chain with the chain builder.
4. Network interception
Company proxies, captive Wi-Fi portals and VPN/filter profiles can break TLS. Test on mobile data.
5. Certificate pinning mismatch
If the app pins a certificate or public key and the server rotated its certificate, the app's own pinning code rejects the connection, often surfacing as -1200 or a cancelled request (-999).
What it looks like on each device
| Context | What you see |
|---|---|
| iOS / macOS app logs | NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." |
| Same server in Safari | "Safari can't establish a secure connection" |
| Untrusted certificate in an app | NSURLErrorDomain Code=-1202 |
| Android apps | Trust anchor for certification path not found or SSLHandshakeException |
How site owners fix it
A server with TLS 1.2 or newer, ECDHE ciphers and a compliant public certificate fixes it without app changes.
1. Bring the server up to ATS standards.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_certificate /etc/nginx/ssl/api.example.com.fullchain.pem;
2. Use a public certificate with a full chain. Check with curl ssl.sh/example.com.
3. If you cannot change the server, add a narrow exception in the app's Info.plist for that domain only:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>legacy.example.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
4. Plan pin rotations by pinning to more than one key, and update the app before the server certificate changes.
FAQ
What is the difference between -1200 and -1202?
-1200 means the secure connection itself failed (protocol, cipher, or a fatal alert during the handshake). -1202 means the handshake worked far enough to receive a certificate, but the certificate is not trusted. -1202 points to the certificate or chain; -1200 points to TLS settings or interference.
Should I set NSAllowsArbitraryLoads to fix it?
No. It disables ATS for all connections, weakens the app's security, and App Review asks for justification. Fix the server, or, if you do not control it, add a narrow exception for that one domain with the specific relaxation it needs.
The error only happens on some users' phones. Why?
Those users may be on networks that intercept TLS (company Wi-Fi, captive portals), have VPN or filtering profiles installed, or run older iOS versions. Collect the underlying _kCFStreamErrorCodeKey value from logs; for example -9802 means a fatal TLS alert and -9806 means the connection was closed.