Message d’erreur
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Également affiché sous la forme
- curl: (56) OpenSSL SSL_read: OpenSSL/3.5.7: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Les versions récentes de curl insèrent la version de la bibliothèque TLS après « SSL_read: » (par exemple « OpenSSL/3.5.7: »). OpenSSL 1.1.1 ne signalait pas cette situation de cette façon ; avec 1.1.1, la même troncature apparaît généralement sous la forme « curl: (18) transfer closed with N bytes remaining to read ».
curl (OpenSSL 3 backend) — CURLE_RECV_ERROR, SSL_R_UNEXPECTED_EOF_WHILE_READING
Ce que cela signifie
La connexion TLS était établie et des données circulaient, puis le pair a fermé la connexion TCP sans envoyer d’abord le close_notify TLS, alors que curl attendait encore des données. OpenSSL 3 signale une fin aussi abrupte comme une erreur plutôt que comme une fin de flux normale, car un close_notify manquant est précisément ce à quoi ressemble une attaque par troncature. curl la signale comme un échec de réception (code de sortie 56).
Pourquoi cela se produit
Le processus serveur a planté ou dépassé son délai en pleine réponse
fréquenteUn processus applicatif tué par un délai d’expiration ou par manque de mémoire, le redémarrage d’un worker PHP-FPM ou Gunicorn, ou un serveur amont qui abandonne ferment le socket alors que le corps de la réponse est encore en cours d’envoi.
Un équipement intermédiaire a coupé la connexion
fréquenteLes pare-feu, passerelles NAT, proxys d’entreprise et répartiteurs de charge qui imposent des limites d’inactivité ou de durée maximale peuvent interrompre un long téléchargement ou une réponse lente au niveau TCP, sans aucune fermeture TLS de la part du serveur.
Le serveur termine ses réponses sans close_notify
occasionnelleCertains serveurs web embarqués, d’anciennes versions d’IIS et des serveurs TLS écrits à la main ferment le socket sans fermeture TLS. Avec des réponses HTTP délimitées par la fermeture de la connexion, les clients OpenSSL 3 signalent chacune de ces réponses par cette erreur.
Une limite de taille du corps a interrompu le transfert
occasionnelleLes limites d’envoi (client_max_body_size, règles WAF) ou les quotas de téléchargement réinitialisent parfois la connexion au lieu de renvoyer une réponse 413 ou 403 en bonne et due forme.
Comment corriger l’erreur
- 1.
Trouver quel maillon ferme la connexion
Notez combien d’octets et combien de secondes s’écoulent avant l’erreur, puis répétez la requête directement vers le backend. Une coupure après un nombre rond de secondes indique un délai d’expiration dans un proxy ou un répartiteur de charge.
bash # How much arrived, and for how long, before the connection died? curl -sv --trace-time https://api.example.com/export.csv -o out.csv 2>&1 | tail -20 # Same request directly to the backend, bypassing the proxy / load balancer curl -sv --resolve api.example.com:443:10.0.0.12 https://api.example.com/export.csv -o out.csv - 2.
Augmenter le délai d’expiration qui se déclenche
Dans le composant qui coupe la connexion, relevez la limite au-delà du plus long temps de réponse légitime, ou faites répondre plus vite le point de terminaison lent (diffusez en flux ou paginez les gros exports).
text # nginx in front of a slow upstream (both default to 60s) proxy_read_timeout 300s; proxy_send_timeout 300s; # Load balancers: set the idle timeout above the longest legitimate response time - 3.
Relancer les transferts idempotents
Pour les téléchargements sur des liaisons peu fiables, laissez curl réessayer et reprendre le transfert. Cela traite le symptôme côté client pendant que vous enquêtez côté serveur.
bash # For idempotent downloads: retry, and resume where the transfer stopped curl --retry 5 --retry-all-errors -C - -o big.iso https://downloads.example.com/big.iso - 4.
Code serveur : fermer proprement les connexions TLS
Envoyez close_notify avant de fermer le socket (SSL_shutdown dans OpenSSL, unwrap() en Python, Close() sur un tls.Conn de Go) et délimitez les corps HTTP avec Content-Length ou l’encodage chunked, pour qu’une fin propre soit sans ambiguïté.
python # Server code: shut TLS down cleanly so the peer receives close_notify conn.unwrap() # Python ssl.SSLSocket: sends close_notify before closing conn.close()
Erreurs associées
error:0A000126:SSL routines::unexpected eof while readingOpenSSL 3[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocolPython ssl module (OpenSSL)GnuTLS recv error (-110): The TLS connection was non-properly terminated.git over HTTPS with libcurl-gnutls (Debian, Ubuntu)curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version numbercurl (OpenSSL backend)