Skip to content
ecdsa.com
Python ssl module (OpenSSL)Python cryptography

Error message

[SSL: WRONG_VERSION_NUMBER] wrong version number

Also printed as

  • ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number

Followed by a source location such as "(_ssl.c:1082)". urllib shows it inside "<urlopen error …>", requests and urllib3 inside "Max retries exceeded … (Caused by SSLError(…))".

Python ssl module (OpenSSL) — ssl.SSLError, SSL_R_WRONG_VERSION_NUMBER

What it means

Python started a TLS handshake, and the bytes that came back are not a TLS record: OpenSSL reads them as a record header with an impossible protocol version. In practice the peer speaks plain text on that port — an HTTP server, a proxy expecting plain HTTP, or an SMTP server waiting for its greeting exchange before STARTTLS.

Why it happens

How to fix it

  1. 1.

    Find out what the port speaks

    Request the port with http:// and try a TLS handshake with openssl s_client; then use the matching scheme or the correct port.

    bash
    curl -si http://127.0.0.1:8080/ | head -1          # an HTTP status line: the port is plain HTTP
    openssl s_client -connect 127.0.0.1:8443 -brief </dev/null   # a TLS summary: the port speaks TLS
  2. 2.

    Write proxy URLs with http://

    The https entry of the proxies mapping names the proxy for HTTPS destinations; its URL scheme describes how to talk to the proxy itself. Traffic to the destination is still end-to-end TLS.

    python
    import requests
    
    # Most forward proxies take plain HTTP from the client and tunnel TLS with CONNECT
    proxies = {"https": "http://proxy.example.net:3128"}   # http:// here, not https://
    requests.get("https://api.example.com/", proxies=proxies)
  3. 3.

    Mail: match the class to the port

    Use SMTP + starttls() on 587 and SMTP_SSL on 465; the same rule applies to imaplib and poplib.

    python
    import smtplib, ssl
    
    ctx = ssl.create_default_context()
    # Port 587: plain connection first, then STARTTLS
    with smtplib.SMTP("mail.example.com", 587) as s:
        s.starttls(context=ctx)
    # Port 465: implicit TLS from the first byte
    with smtplib.SMTP_SSL("mail.example.com", 465, context=ctx) as s:
        s.noop()

Related errors

Browse the full signature error database