Message d’erreur
[SSL: WRONG_VERSION_NUMBER] wrong version number
Également affiché sous la forme
- ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number
Suivi d’un emplacement dans le code source, comme « (_ssl.c:1082) ». urllib l’affiche dans « <urlopen error …> », requests et urllib3 dans « Max retries exceeded … (Caused by SSLError(…)) ».
Python ssl module (OpenSSL) — ssl.SSLError, SSL_R_WRONG_VERSION_NUMBER
Ce que cela signifie
Python a commencé un handshake TLS, et les octets reçus en retour ne forment pas un enregistrement TLS : OpenSSL les lit comme un en-tête d’enregistrement doté d’une version du protocole impossible. En pratique, le pair parle en clair sur ce port – un serveur HTTP, un proxy qui attend du HTTP en clair, ou un serveur SMTP qui attend l’échange de salutations précédant STARTTLS.
Pourquoi cela se produit
https:// vers un port HTTP en clair
fréquenteLes serveurs de développement, les services internes placés derrière un répartiteur de charge qui termine TLS et les points de terminaison de métriques écoutent souvent en HTTP en clair. Utiliser https:// avec leur port produit immédiatement cette erreur.
Le proxy est configuré en https:// mais parle HTTP
fréquenteHTTPS_PROXY=https://proxy:3128 ou proxies={"https": "https://…"} amène urllib3 à démarrer TLS avec le proxy. Depuis urllib3 1.26, cette valeur est appliquée à la lettre, et la plupart des proxys d’entreprise n’acceptent que du HTTP en clair de la part des clients.
smtplib.SMTP_SSL sur un port STARTTLS
fréquenteLe port 587 (comme le 25) commence en clair et passe à TLS avec STARTTLS ; le TLS implicite se trouve sur le 465. SMTP_SSL sur le 587 échoue de cette façon, tout comme IMAP4_SSL sur le 143.
Un portail captif ou un filtre répond en HTTP en clair
occasionnelleLe Wi-Fi des hôtels ou des réseaux invités et certains équipements de sécurité interceptent la connexion et répondent par une page HTTP.
Comment corriger l’erreur
- 1.
Déterminer le protocole que parle le port
Interrogez le port avec http:// et tentez un handshake TLS avec openssl s_client ; utilisez ensuite le schéma correspondant ou le bon 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.
Écrire les URL de proxy avec http://
L’entrée https du dictionnaire proxies désigne le proxy à utiliser pour les destinations HTTPS ; le schéma de son URL indique comment communiquer avec le proxy lui-même. Le trafic vers la destination reste protégé par TLS de bout en bout.
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.
Messagerie : choisir la classe selon le port
Utilisez SMTP + starttls() sur le 587 et SMTP_SSL sur le 465 ; la même règle s’applique à imaplib et à 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()
Erreurs associées
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)