Сообщение об ошибке
[SSL: WRONG_VERSION_NUMBER] wrong version number
Также выводится как
- ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number
Далее следует место в исходном коде, например «(_ssl.c:1082)». urllib показывает сообщение внутри «<urlopen error …>», а requests и urllib3 — внутри «Max retries exceeded … (Caused by SSLError(…))».
Python ssl module (OpenSSL) — ssl.SSLError, SSL_R_WRONG_VERSION_NUMBER
Что это означает
Python начал TLS-рукопожатие, но в ответ пришли байты, которые не образуют запись TLS: OpenSSL читает их как заголовок записи с невозможной версией протокола. На практике другая сторона работает на этом порту без шифрования — это HTTP-сервер, прокси, ожидающий обычный HTTP, или SMTP-сервер, который перед STARTTLS ждёт обмена приветствиями.
Почему это происходит
https:// на порт с обычным HTTP
частоСерверы разработки, внутренние сервисы за балансировщиком нагрузки, завершающим TLS, и эндпоинты метрик часто работают по обычному HTTP. Если обратиться к их порту по https://, эта ошибка возникает сразу.
Прокси указан как https://, но работает по HTTP
частоИз-за HTTPS_PROXY=https://proxy:3128 или proxies={"https": "https://…"} urllib3 устанавливает TLS-соединение с самим прокси. Начиная с urllib3 1.26 эта настройка выполняется буквально, а большинство корпоративных прокси принимают от клиентов только обычный HTTP.
smtplib.SMTP_SSL на порту STARTTLS
частоНа порту 587 (и 25) сеанс начинается без шифрования и переходит на TLS командой STARTTLS; неявный TLS работает на порту 465. SMTP_SSL при подключении к порту 587 выдаёт эту ошибку, как и IMAP4_SSL при подключении к порту 143.
Captive-портал или фильтр отвечает по обычному HTTP
иногдаWi-Fi в отелях и другие гостевые сети, а также некоторые устройства защиты перехватывают соединение и отвечают HTTP-страницей.
Как исправить
- 1.
Выясните, по какому протоколу работает порт
Обратитесь к порту по http:// и попробуйте выполнить TLS-рукопожатие через openssl s_client; затем используйте подходящую схему или правильный порт.
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.
Указывайте URL прокси с http://
Запись https в словаре proxies задаёт прокси для адресов назначения по HTTPS, а схема в URL этого прокси описывает, как обращаться к самому прокси. Трафик до адреса назначения всё равно идёт по сквозному 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.
Почта: выбирайте класс по порту
Используйте SMTP + starttls() на порту 587 и SMTP_SSL на порту 465; то же правило действует для imaplib и 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()
Связанные ошибки
curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version numbercurl (OpenSSL backend)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: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocolPython ssl module (OpenSSL)