Skip to content
ecdsa.com
curl (OpenSSL backend)curl

Error message

curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version number

Also printed as

  • curl: (35) error:0A00010B:SSL routines::wrong version number
  • curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number

Recent curl releases (8.14.1 here) put "TLS connect error: " before the OpenSSL reason; curl 7.x printed the reason alone. OpenSSL 1.1.1 builds print the long form "error:1408F10B:SSL routines:ssl3_get_record:wrong version number"; OpenSSL 3.x prints "error:0A00010B:SSL routines::wrong version number".

curl (OpenSSL backend) — CURLE_SSL_CONNECT_ERROR, SSL_R_WRONG_VERSION_NUMBER

What it means

curl sent a TLS ClientHello and the first bytes that came back were not a TLS record. OpenSSL reads the record header's version field from that reply and finds garbage, typically the letters of "HTTP/1.1 400" from a plain-HTTP server. Despite the wording, this is almost never about TLS versions: the other side is not speaking TLS on that port.

Why it happens

How to fix it

  1. 1.

    Check what the port actually speaks

    Request the same port with http://. If you get an HTTP response, either use http:// or the real TLS port; openssl s_client confirms which ports complete a TLS handshake.

    bash
    # What does the port speak? An HTTP status line means plain HTTP.
    curl -sS -i http://api.example.com:8080/ | head -1        # HTTP/1.1 200 OK  -> not TLS
    openssl s_client -connect api.example.com:8443 -brief </dev/null   # handshake summary -> TLS
  2. 2.

    Use http:// for the proxy URL

    Unless your proxy explicitly supports TLS to the proxy, write the proxy as http://host:port. The connection to the destination is still end-to-end TLS through the CONNECT tunnel.

    bash
    # Most corporate proxies accept plain HTTP from the client and tunnel HTTPS with CONNECT
    export HTTPS_PROXY=http://proxy.example.net:3128     # http:// even for HTTPS traffic
    curl -x http://proxy.example.net:3128 https://api.example.com/
  3. 3.

    Use STARTTLS on STARTTLS ports

    For mail protocols, curl upgrades with --ssl-reqd on the submission and IMAP ports, or uses implicit TLS on 465 and 993 with the smtps:// and imaps:// schemes.

    bash
    # Port 587/25 (SMTP) and 143 (IMAP) start in plain text and upgrade with STARTTLS
    curl --ssl-reqd smtp://mail.example.com:587 -v
    # Implicit TLS lives on 465 (SMTPS) and 993 (IMAPS)
    curl smtps://mail.example.com:465 -v
  4. 4.

    Server owners: enable TLS on the listener

    If clients should use https:// on this port, the listener needs TLS turned on and a certificate configured; otherwise publish the correct port.

    text
    # nginx: the port that clients reach with https:// needs the ssl flag
    server {
        listen 443 ssl;
        ssl_certificate     /etc/nginx/tls/fullchain.pem;
        ssl_certificate_key /etc/nginx/tls/privkey.pem;
    }

Related errors

Browse the full signature error database