एरर समाधान · डेवलपर एरर

SSL wrong version number: Why It Happens and How to Fix It

The OpenSSL error wrong version number means a TLS client got non-TLS bytes back. Find the plain-HTTP port, the HTTPS-to-HTTP proxy setting or STARTTLS mix-up behind it.

Error messageerror:0A00010B:SSL routines::wrong version number

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 28, 2026 · 4 मिनट पढ़ने में

When a TLS client sends its opening message, it expects a TLS record in reply. If the first bytes that come back are not a valid TLS record, OpenSSL reports wrong version number. Despite the name, this is rarely a real version disagreement. It almost always means the other end is not speaking TLS on that port.

How it appears:

curl: (35) error:0A00010B:SSL routines::wrong version number
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
requests.exceptions.SSLError: ... [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)

The first is OpenSSL 3, the second OpenSSL 1.x. A genuine TLS version problem normally produces protocol version or tlsv1 alert protocol version instead. See sslv3 alert handshake failure for those.

Causes, most likely first

  1. HTTPS to a plain HTTP port. You used https:// against a port serving HTTP, such as 80, 8080 or a dev server on 3000. The server replies with something like HTTP/1.1 400 Bad Request, whose first bytes OpenSSL cannot read as TLS.
  2. An HTTPS proxy setting that points at an HTTP proxy. https_proxy=https://proxy.corp:3128 makes the client try TLS to the proxy itself. Most proxies speak plain HTTP on that port and use CONNECT for the tunnel, so the correct value is http://proxy.corp:3128. This is the most common cause on corporate networks and CI.
  3. STARTTLS versus implicit TLS mismatch. SMTP on 587 or 25, IMAP on 143 and others begin in plain text and upgrade. Connecting with implicit TLS to those ports fails this way, as does the reverse on 465/993/995.
  4. A service listening without TLS after a misconfiguration: listen 443; without ssl in nginx, or a virtual host missing SSLEngine on in Apache.
  5. Non-HTTP service on the port: SSH, a database or a load balancer in TCP passthrough mode.
  6. A captive portal or middlebox replying with its own HTML or a TCP reset.

Step 1: see what is really on the port

Ask for plain HTTP on the same port:

curl -v http://example.com:8443/

If that returns a normal HTTP response, the port is not TLS. Alternatively, connect raw and look:

printf 'HEAD / HTTP/1.0\r\n\r\n' | nc example.com 8443

Readable HTTP/1.1 ... text confirms plain HTTP. Binary garbage followed by a handshake means TLS. An SSH-2.0-... banner means SSH. The पोर्ट चेकर confirms the port is open, and openssl s_client tells you whether TLS works at all:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>&1 | head -n 20

On a healthy port you see CONNECTED, a certificate chain and SSL-Session. On this failure you see error:0A00010B or no peer certificate available.

Step 2: check proxy variables

env | grep -i proxy
curl -v https://example.com/ 2>&1 | grep -iE "proxy|CONNECT"

Look for https_proxy, HTTPS_PROXY, ALL_PROXY and package-manager settings (npm config get https-proxy, git config --get http.proxy, pip config list). If the value begins with https://, change it to http://, unless you know the proxy genuinely terminates TLS on that port. Test by bypassing it: curl --noproxy '*' https://example.com/.

Step 3: use the right scheme for mail

openssl s_client -starttls smtp -connect mail.example.com:587 -crlf
openssl s_client -connect mail.example.com:465 -crlf      # implicit TLS
openssl s_client -starttls imap -connect mail.example.com:143

Use -starttls for upgrade-style ports, and no flag for implicit TLS ports. In client libraries, the matching toggles are often named secure, use_tls or starttls; setting both or neither causes this error.

If you own the server

Make sure TLS is actually enabled on the listener.

server {
    listen 443 ssl;          # "ssl" is required; plain "listen 443;" serves HTTP
    server_name example.com;
    ssl_certificate     /etc/ssl/example.com/fullchain.pem;
    ssl_certificate_key /etc/ssl/example.com/privkey.pem;
}
<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/ssl/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/ssl/example.com/privkey.pem
</VirtualHost>

After a reload, run sudo ss -ltnp | grep :443 to confirm the right process owns the port. In containers, check that the published port maps to the TLS listener and not the HTTP one. Behind a load balancer, check whether the backend protocol is set to HTTP or HTTPS and match it to what your app serves. A mismatch there can show up as this error or as 502s.

Verify

Repeat the failing command; success looks like an HTTP status line. Check the endpoint using the HTTP स्टेटस चेकर and the SSL Checker, and add a monitor so a bad deploy cannot silently turn off TLS.

अगले कदम

सामान्य प्रश्न

Is it a TLS version problem?

Rarely. It means the response was not a TLS record at all. Real version disagreements show protocol version alerts.

Why do I get it only through the corporate proxy?

Your proxy variable probably starts with https:// while the proxy speaks plain HTTP. Change the scheme to http://.

Why do I get it on port 587?

Port 587 normally uses STARTTLS. Connect in plain text first and upgrade, rather than starting TLS immediately.

Can a WAF or CDN cause it?

Yes, if its origin-side protocol setting disagrees with what your origin serves. Match the origin protocol and port in the CDN configuration.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.