SSL Connect Error: What Causes It and How to Fix It (curl 35, SSL_connect)
If you have ever run a `curl` command or loaded an application that talks to an HTTPS endpoint and been met with a blunt `SSL connect error` — often shown as curl error 35 or `SSL_connect: …` — you already know how unhelpful that message can feel. It does not tell you whether the certificate is bad, the server is down, or something between your machine and the server is quietly dropping packets.
This guide explains exactly what an SSL connect error means, separates it from the handshake and verification errors it is frequently confused with, and walks through the common causes and fixes using real `openssl` and `curl` diagnostics.
Key Takeaways
• An SSL connect error means the TLS connection could not be established at all — it fails *before* certificate validation.
• The most common root causes are blocked port 443, a wrong port, a server not speaking TLS on that port, or a TLS version / cipher mismatch — not a bad certificate.
• Diagnose with `openssl s_client -connect host:443` and `curl -v` to see exactly where the connection stops.
• A “connect error” is different from a “handshake” or “verification” error; treating them the same wastes hours.
What does an SSL connect error actually mean?
An SSL connect error signals that your client tried to open a TLS session with a server and the session never came up. In `curl`, this surfaces as exit code 35 with text such as `error:0A000126:SSL routines::unexpected eof while reading` or `OpenSSL SSL_connect: Connection reset by peer`.
The critical thing to understand is where in the process it fails. A TLS connection has three rough stages:
- TCP connect — your client opens a socket to the server’s IP on a port (usually 443).
- TLS handshake — client and server agree on a protocol version and cipher suite, then exchange keys.
- Certificate verification — your client checks the server’s certificate against trusted CAs.
A connect error lives in stages 1 and 2. The handshake either never starts or collapses mid-negotiation. This is fundamentally different from a verification error (stage 3), which produces messages like `certificate has expired` or `unable to get local issuer certificate`. Those mean the handshake *succeeded* but the certificate was not trusted.
Bold rule of thumb: if you see “connect error,” suspect connectivity and protocol negotiation first, and the certificate last.
Why do most people misdiagnose an SSL connect error?
Because the word “SSL” is in the message, the instinct is to inspect the certificate — renew it, reinstall the chain, check the expiry. But a connect error usually happens before any certificate is even presented.
Here is the insight that saves the most time: an SSL connect error often means the problem is *before* the handshake. The port may be firewalled, you may be hitting the wrong port, or the server may not be speaking TLS on that port at all (for example, a plain HTTP service listening on 443, or nothing listening on 443). Verify raw connectivity before you ever touch the certificate. If a TCP connection to `host:443` does not even open, no certificate change in the world will fix it.
What are the common causes and fixes?
The table below maps each symptom to its likely cause and the fix. Use it alongside the diagnostics in the next section.
| Symptom / message | Likely cause | Fix |
|---|---|---|
| `curl: (7) Failed to connect … port 443` | Port 443 blocked by firewall or nothing listening | Open 443 in the firewall/security group; confirm the web server is running and bound to 443 |
| `Connection reset by peer` during handshake | Server not speaking TLS on that port, or proxy interfering | Confirm TLS is configured on 443; try the correct port; bypass the proxy |
| `wrong version number` | You sent TLS to a plain-HTTP port (or vice versa) | Use the correct port and scheme (`https://` vs `http://`) |
| `no protocols available` / `unsupported protocol` | TLS version mismatch — client wants a version the server disabled (or vice versa) | Align TLS versions; update client to support TLS 1.2/1.3; re-enable a modern version server-side |
| `sslv3 alert handshake failure` / `no cipher` | Cipher suite mismatch | Update OpenSSL; configure modern, overlapping ciphers on the server |
| `unexpected eof while reading` | Connection dropped mid-handshake (firewall, MTU, idle proxy) | Check firewall/proxy; test from another network |
| Works in browser, fails in script | Outdated curl/openssl/client library | Update `curl`/`openssl`/the language’s TLS library |
| Intermittent failures | DNS pointing to wrong host, or load balancer node misconfigured | Verify DNS/IP; test each backend directly |
| `SNI`-related handshake failure | SNI not sent or wrong hostname on a shared IP | Ensure the client sends SNI; connect by the correct hostname, not the bare IP |
TLS version and cipher mismatches
Modern servers commonly disable TLS 1.0 and 1.1. An old client library or an ancient `curl` build may only offer those, so the handshake fails with `no protocols available` or an `unsupported protocol` alert. The reverse also happens: a hardened client requires TLS 1.3 while the server tops out at TLS 1.2. The fix is to make the supported versions overlap — usually by updating the client and ensuring the server offers TLS 1.2 and 1.3.
Firewalls, proxies, and the wrong port
A corporate firewall, cloud security group, or transparent proxy can silently block or reset port 443. A wrong port is equally common: pointing HTTPS at a port that only serves plain HTTP yields `wrong version number`, because the server replies with HTTP text where the client expects a TLS record.
Server not configured for TLS
If SSL was never set up on the server, or the virtual host is missing, the server may accept the TCP connection and then immediately reset it — producing `Connection reset by peer`. The certificate is irrelevant here; TLS termination simply is not configured on that listener.
How do you diagnose an SSL connect error with openssl and curl?
Two commands resolve the vast majority of cases. Run them in order.
Step 1 — Test the TLS connection directly with `openssl`:
“`bash openssl s_client -connect example.com:443 -servername example.com “`
The `-servername` flag sends SNI, which matters on shared IPs. Read the output carefully:
- If it hangs or fails to connect, the problem is TCP/firewall/port — not the certificate.
- If you see `Verify return code: 0 (ok)` and a certificate chain, TLS is working and your real issue is elsewhere (likely verification or application logic).
- If you see `wrong version number`, you are hitting a non-TLS port.
- If you see an alert like `no protocols available`, it is a version mismatch — pin a version to confirm:
“`bash openssl s_client -connect example.com:443 -tls1_2 openssl s_client -connect example.com:443 -tls1_3 “`
Step 2 — Reproduce with verbose `curl`:
“`bash curl -v https://example.com “`
The `-v` output shows each stage: `Trying
“`bash curl -v telnet://example.com:443
nc -vz example.com 443 “`
If that connection does not open, you have a network/port problem, full stop. To test a specific TLS version with curl:
“`bash curl -v –tlsv1.2 https://example.com “`
Step 3 — Confirm versions of your own tooling:
“`bash curl –version openssl version “`
An old OpenSSL bundled with your client library is a frequent, easily missed cause of connect failures against modern servers.
How DarazHost prevents SSL connect errors for you
Many SSL connect errors trace back to server-side TLS configuration — the layer you control when you choose the right host. DarazHost is built so the connection comes up cleanly the first time:
- Correctly configured SSL/TLS on port 443 with free SSL certificates and AutoSSL, so issuance, installation, and renewal are handled automatically — no missing listeners, no half-configured virtual hosts.
- Modern TLS (1.2 and 1.3) with complete certificate chains, eliminating the version-mismatch and incomplete-chain problems that cause handshakes to fail.
- Open, correctly routed ports so port 443 is reachable and actually serving TLS — not blocked or pointed at the wrong service.
- VPS plans with full root access, giving you direct control to tune TLS versions, cipher suites, and web-server configs when you need it.
- 24/7 expert support that troubleshoots SSL connect and handshake issues with you, instead of leaving you to decode `curl` exit codes alone.
If you are tired of fighting TLS configuration, , or about migrating an existing site.
How do you fix it once you know the cause?
Work outward from the network:
- Confirm the port opens (`nc -vz host 443`). If not, fix the firewall/security group or start the service.
- Confirm the port speaks TLS (`openssl s_client`). If you get `wrong version number`, correct the port or scheme.
- Align TLS versions and ciphers — update the client, and make sure the server offers TLS 1.2/1.3 with overlapping ciphers.
- Update your tooling (`curl`, `openssl`, language TLS libraries) so an outdated client is not the cause.
- Only then investigate the certificate — and at that point you are usually dealing with a *verification* error, not a connect error.
Frequently asked questions
Is an SSL connect error the same as a certificate error? No. A connect error happens before certificate validation — the TLS session never fully establishes. Certificate errors (expired, untrusted, incomplete chain) occur *after* a successful handshake. The fixes are completely different, which is why distinguishing them first is essential.
What does curl error 35 specifically mean? Exit code 35 is curl’s generic “a problem occurred during the SSL/TLS handshake.” It covers blocked connections, protocol mismatches, abrupt resets, and unsupported ciphers. Run `curl -v` to see the exact stage where it stopped, then match that against the causes-and-fixes table above.
Why does it work in my browser but fail in curl or my app? Usually because the browser ships a modern, frequently updated TLS stack, while your `curl`, `openssl`, or language library is older and only offers deprecated TLS versions or ciphers the server has disabled. Update the client tooling and retest.
How do I know if port 443 is blocked? Test raw connectivity with `nc -vz host 443` or `curl -v telnet://host:443`. If the TCP connection does not open, the port is blocked or nothing is listening — a network problem, not a certificate problem. Check firewalls, cloud security groups, and any proxy in the path.
Can a proxy cause an SSL connect error? Yes. A transparent or corporate proxy can intercept, reset, or fail to forward TLS traffic, producing resets or `unexpected eof` mid-handshake. Test from a different network or with the proxy disabled to confirm whether the proxy is the culprit.