
When an HTTPS request from a Linux server fails with curl: (35), that line alone does not tell you whether the problem is a certificate, a protocol mismatch, or a network device. curl defines error 35 as a failure during the SSL/TLS handshake. The accompanying error message, actual destination, and TLS backend are needed to narrow it down. [1]
This guide follows one request through the troubleshooting process: capture the failure, check the hostname and destination IP, compare TLS versions and proxy paths, and correlate the result with server logs. These are diagnostic examples, not tests performed in your production environment or evidence of a current CloudFlew service issue.
Scope: curl and the OpenSSL command-line tools on Linux. Replace example.com and 203.0.113.10 with a hostname and IP you are authorized to test. Use a harmless test endpoint without production cookies, tokens, or business data. Check the locally installed version's help before using an option.
1. Distinguish error 35 from error 60 and HTTP status codes
Error 35 means the handshake failed. Possible causes include protocol negotiation, certificate-related configuration, or an interrupted connection. Error 60 generally indicates failed peer-certificate verification, such as a trust-chain or hostname check. The two codes do not justify the same diagnosis. [1]
HTTP status codes such as 403 and 502 belong to a later layer. If curl receives an HTTP response over HTTPS from a CDN, TLS has been established between the client and that responding endpoint. The CDN may still have a separate connection problem with the origin. Identify which connection leg failed before changing settings.
2. Capture the failure before reaching for --insecure
curl -V openssl version curl -v --connect-timeout 10 --max-time 20 \ --output /dev/null https://example.com/
curl -V identifies the curl version, TLS library, and compiled features. The openssl executable on the same server does not necessarily use the same TLS library or trust store as curl, so different results from the two tools are not inherently contradictory. [2]
In verbose output, record the destination IP, whether a proxy is involved, whether the connection was established, and the text following SSL_connect. A timeout, reset, protocol-version alert, and certificate-verification failure are different clues. SSL_ERROR_SYSCALL by itself still does not establish the root cause.
Verbose output can expose request headers, authentication data, and internal addresses. Redact it before sharing, and do not paste token-bearing logs into public posts or support tickets. The time limits above keep an individual diagnostic request bounded. [2]
Do not make -k or --insecure your repair. It disables certificate verification, weakens security, and does not fix most protocol mismatches or interrupted connections. For error 60, investigate the certificate chain, hostname, system time, and trusted CA configuration instead of permanently disabling verification. [1][2]
3. Preserve the hostname and SNI when testing an IP
Requesting https://IP/ and adding a Host header does not fully reproduce normal hostname-based access. TLS negotiation occurs before the HTTP request; an HTTP Host header cannot replace SNI in the handshake. The hostname in the URL also matters for certificate-name verification.
curl -v --connect-timeout 10 --max-time 20 \ --resolve example.com:443:203.0.113.10 \ --output /dev/null https://example.com/
--resolve supplies a hostname, port, and address mapping for this command. Keeping the hostname in the URL makes it useful for comparing authorized endpoints without changing the requested identity. [2]
Make this comparison on a confirmed direct path without an explicit proxy. With a proxy involved, the proxy may determine the destination; --resolve alone does not prove that a request reached the specified origin. Do not bypass organizational egress restrictions to run the test.
If one address works and another fails, compare their certificate deployment, listeners, TLS policies, and network paths. That narrows the investigation; one request is not proof of a DNS or CDN outage. Direct origin access must also be permitted. An origin configured to accept only CDN traffic may reject direct connections by design.
4. Inspect the handshake and certificates with OpenSSL
timeout 20s openssl s_client \ -connect 203.0.113.10:443 \ -servername example.com \ -verify_hostname example.com \ -verify_return_error -showcerts </dev/null
-servername explicitly sends hostname SNI. -verify_hostname checks the certificate hostname, and -verify_return_error makes verification errors stop the connection. Without the latter option, s_client can report a verification error and continue because it is a diagnostic tool. [3]
-showcerts displays the certificates actually sent by the server; it is not proof of a complete, verified chain. Inspect the verification result, negotiated protocol, and server alerts together. For private PKI, use a trusted CA file supplied by your administrator rather than downloading a certificate from an error page and trusting it. [3]
The timeout utility limits how long this example runs. If it is unavailable, run s_client in a controlled terminal and end the diagnostic session after inspection. OpenSSL and curl may differ in TLS backend, CA paths, and proxy configuration; record those differences when comparing their output.
5. Compare TLS 1.2 and TLS 1.3 without changing production policy
curl -v --tlsv1.2 --tls-max 1.2 \ --connect-timeout 10 --max-time 20 \ --output /dev/null https://example.com/ curl -v --tlsv1.3 --tls-max 1.3 \ --connect-timeout 10 --max-time 20 \ --output /dev/null https://example.com/
--tlsv1.2 sets a minimum of TLS 1.2, not an exact version. Pairing it with --tls-max 1.2 restricts the test to TLS 1.2. The TLS 1.3 test requires a curl TLS backend that supports that version. [2]
If TLS 1.2 succeeds and TLS 1.3 fails, investigate client capabilities, server policy, and intervening proxies or security devices. Keep the endpoint and network path consistent where possible so a node difference is not mistaken for a protocol difference. Do not disable TLS 1.3 site-wide or enable obsolete protocols and weak ciphers based on one comparison.
6. Check HTTPS_PROXY and the proxy URL scheme
A browser that works and a server-side curl command that fails may use different proxies, TLS libraries, or trust stores. curl can read HTTPS_PROXY, ALL_PROXY, and NO_PROXY; its default configuration file can also affect a request. Inspect settings locally without printing full proxy URLs that contain credentials. [2]
The name HTTPS_PROXY identifies the destination protocol it applies to. The http:// or https:// scheme in its value describes how the client connects to the proxy. A conventional HTTP CONNECT proxy can carry traffic to an HTTPS destination. Marking a plaintext HTTP proxy endpoint as https:// can cause errors such as wrong version number. Confirm this against verbose output rather than assuming every occurrence has the same cause.
Only where direct access is authorized, use this one-request comparison:
curl -q --noproxy '*' -v \ --connect-timeout 10 --max-time 20 \ --output /dev/null https://example.com/
-q must be the first option to skip curl's default configuration file. The wildcard passed to --noproxy disables curl's explicit proxy use for this request. It does not bypass transparent proxies, firewalls, or egress gateways, and it does not change system-wide proxy settings. If your organization requires a proxy, skip this comparison and ask the network administrator to inspect its logs. [2]
7. Correlate client failures with TLS endpoint logs
If the hostname, endpoint, and proxy path are understood but the handshake still fails, inspect logs from the actual TLS termination point. That may be a CDN, load balancer, or reverse proxy rather than the application server. Record the test time and timezone, destination IP, hostname, protocol version, and redacted error text.
Look for protocol restrictions, cipher mismatches, client-certificate requirements, unmatched virtual hosts, and connection resets. An endpoint requiring mutual TLS needs the appropriate client certificate and private key, configured according to the provider's requirements. Never upload private keys to a public diagnostic website.
If you cannot access the logs, send the sanitized evidence to the provider. Avoid changing kernel parameters, disabling a WAF, or restarting the whole server simply to test a guess. Those actions may interrupt service and erase useful evidence.
8. Verify the repair through the original access path
After correcting a certificate, proxy address, or server policy, retest using the original application access method—not just temporary diagnostic options. Restore normal DNS resolution, keep certificate verification enabled, and check for the expected HTTP response. A 401 from an authentication-required endpoint does not mean TLS is still failing.
Repeat a small number of checks from the client environment that originally failed and correlate them with endpoint logs. Before changing production configuration, preserve the original values and follow your change process with a limited rollout. Restore the previous configuration if the change introduces problems. The curl options shown here affect only their individual commands; removing them restores ordinary testing and does not require persistent kernel changes.
Frequently asked questions
Does curl error 35 always mean an expired certificate?
No. Error 35 is a handshake-failure category; failed certificate verification generally maps to error 60. Use the detailed error and verification result rather than replacing certificates based on the number alone. [1]
Why does HTTPS fail when ping works?
A successful ping proves neither that TCP port 443 is reachable nor that TLS negotiation can complete. Test the actual HTTPS path and distinguish connection-establishment failures from handshake failures.
If -k makes the request work, can I keep it?
No—not as a production repair. Skipping verification can let the client accept an impersonator's certificate. Correct the trust chain, hostname, or CA configuration responsible for the failure. [2]
What to collect before making the next change
A useful curl error 35 report contains the hostname, actual destination IP, curl and TLS-library versions, proxy path, and complete redacted error message. With these details together, compare endpoints and protocol versions one variable at a time. This reduces unnecessary certificate replacements, TLS downgrades, and service restarts.
References
2. curl: command-line options, proxies, and certificate verification
Sources checked for the Chinese edition on September 10, 2026. This English edition uses the same sources and diagnostic examples. Option availability and behavior depend on the installed version and its corresponding documentation.