Aller au contenu
ecdsa.com
Python ssl module (OpenSSL)cryptography (Python)

Message d’erreur

[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol

Également affiché sous la forme

  • ssl.SSLEOFError: EOF occurred in violation of protocol

Avec OpenSSL 3, Python affiche le code de raison « [SSL: UNEXPECTED_EOF_WHILE_READING] » ; avec OpenSSL 1.1.1, le texte est simplement « EOF occurred in violation of protocol ». Un emplacement dans le code source, comme « (_ssl.c:1082) », suit le message.

Python ssl module (OpenSSL) — ssl.SSLEOFError, SSL_R_UNEXPECTED_EOF_WHILE_READING

Ce que cela signifie

L’autre côté a fermé la connexion TCP alors que Python était encore dans le handshake TLS (ou en pleine lecture de données), sans envoyer d’alerte TLS ni close_notify. OpenSSL traite cette fermeture silencieuse comme une violation du protocole. Python ne peut pas savoir pourquoi le pair est parti ; la raison se trouve du côté du serveur, d’un proxy ou d’un pare-feu situé entre les deux.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Reproduire le handshake avec openssl s_client

    Si s_client est lui aussi déconnecté, faites varier le SNI et la version de TLS pour voir ce que le serveur refuse ; si s_client fonctionne, comparez ses paramètres avec ceux de votre client Python (proxy, SNI, versions).

    bash
    # Does a plain OpenSSL handshake work from the same machine?
    openssl s_client -connect api.example.com:443 -servername api.example.com -brief </dev/null
    # Without SNI, and pinned to TLS 1.2, to see what the server objects to
    openssl s_client -connect api.example.com:443 -noservername -brief </dev/null
    openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2 -brief </dev/null
  2. 2.

    Vérifier les variables d’environnement de proxy

    requests, urllib et pip tiennent compte de HTTPS_PROXY et de NO_PROXY. Corrigez le schéma de l’URL du proxy et excluez les hôtes internes qui doivent être joints directement.

    bash
    env | grep -i -E '^(https?|no|all)_proxy='
    # Proxy URLs should normally be http:// (CONNECT tunnel), and internal hosts listed in NO_PROXY
    export HTTPS_PROXY=http://proxy.example.net:3128
    export NO_PROXY=localhost,127.0.0.1,.internal.example.com
  3. 3.

    Réessayer quand la cause est passagère

    En cas de limitation de débit ou de réseau instable, de nouvelles tentatives espacées par des délais croissants transforment des réinitialisations sporadiques en réussites, simplement plus lentes ; elles ne corrigent pas un serveur qui refuse systématiquement le handshake.

    python
    import requests
    from requests.adapters import HTTPAdapter
    from urllib3.util.retry import Retry
    
    session = requests.Session()
    session.mount("https://", HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1)))
    session.get("https://api.example.com/")

Erreurs associées

Parcourir toute la base de données des erreurs de signature