Сообщение об ошибке
curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version number
Также выводится как
- curl: (35) error:0A00010B:SSL routines::wrong version number
- curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
Последние версии curl (здесь 8.14.1) добавляют перед причиной от OpenSSL «TLS connect error: »; curl 7.x выводил только причину. Сборки с OpenSSL 1.1.1 выводят длинную форму «error:1408F10B:SSL routines:ssl3_get_record:wrong version number», а OpenSSL 3.x — «error:0A00010B:SSL routines::wrong version number».
curl (OpenSSL backend) — CURLE_SSL_CONNECT_ERROR, SSL_R_WRONG_VERSION_NUMBER
Что это означает
curl отправил TLS ClientHello, но первые байты ответа оказались не записью TLS. OpenSSL читает из этого ответа поле версии в заголовке записи и находит там мусор — обычно буквы «HTTP/1.1 400» от сервера, который отвечает по обычному HTTP. Несмотря на формулировку, дело почти никогда не в версиях TLS: на этом порту другая сторона вообще не использует TLS.
Почему это происходит
https:// на порту, где работает обычный HTTP
частоСерверы разработки на портах 8080 или 3000, бэкенд за балансировщиком нагрузки или неверно настроенная директива listen отвечают по HTTP. Самая частая причина этого сообщения — перепутанные http и https в URL или номер TLS-порта, указанный вместе с http://.
В URL прокси указано https://, а прокси работает по HTTP
частоС HTTPS_PROXY=https://proxy:3128 curl устанавливает TLS-соединение с самим прокси. Большинство прямых прокси ждут от клиента обычный HTTP и открывают до целевого сервера зашифрованный туннель CONNECT, поэтому URL прокси следует начинать с http:// даже для HTTPS-трафика.
Неявный TLS на порту STARTTLS
иногдаSMTP на портах 25/587, IMAP на 143, POP3 на 110, LDAP на 389, а также PostgreSQL/MySQL начинают сеанс без шифрования и переходят на TLS позже. Если начать там сразу с TLS-рукопожатия, попытка тут же завершится ошибкой.
Вместо сервера отвечает captive-портал или фильтр
иногдаСети Wi-Fi в отелях и аэропортах, родительские фильтры и некоторые межсетевые экраны перехватывают порт 443 и ещё до начала TLS отвечают HTTP-страницей с перенаправлением.
Как исправить
- 1.
Проверьте, какой протокол на самом деле работает на порту
Обратитесь к тому же порту через http://. Если пришёл HTTP-ответ, используйте либо http://, либо настоящий TLS-порт; openssl s_client покажет, на каких портах TLS-рукопожатие проходит до конца.
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.
Укажите http:// в URL прокси
Если поддержка TLS-соединения с самим прокси явно не заявлена, указывайте прокси как http://host:port. Соединение с целевым сервером при этом всё равно защищено сквозным TLS через туннель CONNECT.
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.
Используйте STARTTLS на портах STARTTLS
Для почтовых протоколов curl переходит на TLS с флагом --ssl-reqd на портах отправки почты и IMAP либо использует неявный TLS на портах 465 и 993 со схемами smtps:// и imaps://.
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.
Владельцам серверов: включите TLS на этом порту
Если клиенты должны обращаться к этому порту по https://, на нём нужно включить TLS и настроить сертификат; в противном случае сообщите клиентам правильный порт.
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; }
Связанные ошибки
SSL routines:tls_validate_record_header:wrong version numberOpenSSL 3 (openssl s_client and any OpenSSL-based client)code: 'ERR_SSL_WRONG_VERSION_NUMBER'Node.js tls.connect / fetch (undici)[SSL: WRONG_VERSION_NUMBER] wrong version numberPython ssl module (OpenSSL)http: server gave HTTP response to HTTPS clientGo net/httpjavax.net.ssl.SSLException: Unsupported or unrecognized SSL messageJava (JSSE)