Error reference cURL

How to Fix cURL Error 35: SSL Connect Error

cURL error 35 — CURLE_SSL_CONNECT_ERROR — means the TLS handshake started but never completed. It is not a certificate-validation failure (that is error 60); something rejected or broke the negotiation itself. The usual suspects are HTTPS pointed at a plaintext port, protocol mismatches, interception in the path, and a wrong proxy URL scheme. Here is how to isolate each one fast.

cURL Error 35: SSL Connect Error

What cURL Error 35 Actually Means

Error 35 is CURLE_SSL_CONNECT_ERROR: the TCP connection succeeded, curl began the TLS handshake, and the negotiation broke before a secure channel existed. The far end sent a fatal alert, reset the connection, or replied with bytes that are not TLS at all. It is distinct from error 60 (certificate verification failed — the handshake got further) and error 28 (nothing answered in time).

Failures cluster into three families. Protocol mismatch: your curl offers TLS versions or ciphers the server will not accept — typical with an outdated OpenSSL build, or with legacy flags like --tlsv1.0 or a hand-rolled --ciphers list forced in an old script. Wrong protocol on the wire: https:// pointed at a plaintext port, or a proxy hop wrongly wrapped in TLS — the plaintext reply cannot parse as a ServerHello, producing OpenSSL's famous "wrong version number". And interference: middleboxes, TLS inspection, or a target that resets handshakes from IP ranges it distrusts.

The wrapped detail narrows it fast: "wrong version number" means plaintext answered; "alert handshake failure" means negotiation was rejected; a bare connection reset during the handshake usually means something dropped you deliberately.

cURL Error 35: SSL Connect Error

How to Fix cURL Error 35, Step by Step

First confirm what is actually listening on the other end of the socket; then narrow protocol and path issues in order.

  1. Check the URL-to-port pairing: https:// against port 80 or any plaintext service fails with error 35, typically with a wrong version number detail.
  2. If a proxy is in play, match the proxy scheme to the port: -x http://host:port is correct for a standard CONNECT proxy. Writing -x https:// makes curl attempt TLS on the proxy hop itself.
  3. Re-run with -v and read the TLS lines — they show the offered protocol version and the exact point the handshake died.
  4. Pin protocol versions as a test: --tlsv1.2 or --tls-max 1.2. If pinning fixes it, one side's supported range is the problem.
  5. Update curl and its TLS library. Old OpenSSL builds cannot complete handshakes with servers that require modern TLS 1.2+ or 1.3 cipher suites.
  6. Cross-check with openssl s_client -connect host:443 -servername host. If that fails too, the fault is in the network path or server, not in curl.
  7. Hunt for TLS interception: corporate security appliances, antivirus HTTPS scanning, and captive portals all mangle handshakes. Compare the same command from a different network.
  8. Delete forced --ciphers, --curves, or legacy version flags inherited from old scripts — over-constraining the handshake is a self-inflicted error 35.
cURL Error 35: SSL Connect Error

Where Proxies Fit Into a TLS Handshake Failure

With an HTTP proxy and an https:// URL, curl connects to the proxy in plaintext, issues CONNECT to open a tunnel, and only then performs the TLS handshake with the target through that tunnel. Error 35 can therefore occur at two different points: on the proxy hop, if you declared the proxy itself as https:// when its port speaks plain HTTP — or inside the tunnel, when the target kills the handshake it sees arriving from the proxy's exit IP.

That second case is the one scrapers hit. Sites defending at the network layer can reset TLS handshakes from IP ranges with poor reputation — most often datacenter blocks — before a single HTTP byte is exchanged. Your TLS stack is fine; the exit IP is the variable. Changing what the target sees, by moving to residential or ISP-grade exits or by rotating to a fresh IP, resolves resets that no client-side flag can.

Get the proxy scheme right

The proxy URL scheme describes the hop to the proxy, not the destination. For HTTPS targets through ProxyOmega, use -x http://USERNAME:[email protected]:10000 — end-to-end TLS still protects the request inside the CONNECT tunnel. Every ProxyOmega port also answers SOCKS5, so socks5h:// is a drop-in alternative on the same port.

Handshake resets are often reputation, not protocol

If handshakes fail only against certain sites and only through certain exits, you are being filtered at TLS time. Rotating residential exits on Budget Unlimited (/plan-unlimited/) or Tier-1 ISP-quality IPs on Platinum (/plan-platinum/) present consumer-grade addresses that these filters are far less inclined to reset on sight.

SOCKS5 as an isolation test

Through SOCKS5, curl tunnels raw TCP and your local TLS stack negotiates directly with the target. If HTTP-proxied requests throw error 35 but the same request via socks5h:// succeeds, the CONNECT layer or scheme was the culprit. Since ProxyOmega serves both protocols on one port, the test is a one-line change.

cURL Error 35: SSL Connect Error

A Correct HTTPS Request Through a Proxy

The proxy hop stays http:// while TLS runs end to end through the tunnel to the target — the standard layout that avoids self-inflicted handshake failures.

# http:// proxy scheme + end-to-end TLS through the CONNECT tunnel
curl -x "http://USERNAME:[email protected]:10000" \
  --tlsv1.2 \
  -sS -o /dev/null \
  -w "TLS ok, HTTP status: %{http_code}\n" \
  "https://example.com/"
FAQ

Frequently asked questions

Is curl error 35 a certificate problem?
No. Certificate-verification failures are error 60, and they happen after the handshake reaches the certificate exchange. Error 35 fires earlier, when negotiation itself breaks down. That is why --insecure does not fix error 35 — it only skips verification. If -k changes nothing, you have confirmed the failure is at the protocol level, not the trust level.
Why do I get error 35 only when using a proxy?
Two likely causes. First, the proxy URL scheme is wrong: declaring the proxy as https:// makes curl attempt TLS on the proxy hop itself, which fails against a plaintext CONNECT port. Second, the target is resetting handshakes coming from that exit IP. Fix the scheme first, then test a different exit or rotation to rule out reputation filtering.
What does the OpenSSL message "wrong version number" mean?
It means the bytes that came back were not TLS — the far end answered in plaintext. Typical triggers: https:// pointed at port 80, a service that only speaks plain HTTP, or a proxy hop wrongly wrapped in TLS. Check the URL, the port, and the proxy scheme; one of the three is speaking the wrong protocol.
Does switching to SOCKS5 avoid TLS handshake errors?
Switching protocols does not change the TLS handshake — it still runs end to end between your client and the target. But it is a useful isolation test: if HTTP proxying fails and SOCKS5 succeeds, the problem sits in the CONNECT layer. On ProxyOmega the same port serves HTTP, HTTPS, and SOCKS5, so testing is a one-line scheme change.

Clean exits, clean handshakes. Start routing today.

ProxyOmega serves HTTP, HTTPS, and SOCKS5 on every port — one endpoint, residential and ISP-quality IPs in 200+ countries.

ProxyOmega ProxyOmega

90M+ ethically-sourced IPs across 200+ countries and 30,000+ cities. Residential, mobile, ISP and IPv6 proxies for scraping and AI agents.

GDPRCCPA
Product
Premium Unlimited Budget Unlimited Residential / ISP Mobile IPv6 Chrome Extension
Solutions
Web scraping AI agents Price monitoring SERP & SEO Integrations All use cases
Resources
Glossary Error codes Free tools Proxies by platform Locations
Company
About Blog Docs Reseller program Affiliate Contact Sign in
© 2026 ProxyOmega Ltd. All rights reserved.