Error message
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Also printed as
- curl: (56) OpenSSL SSL_read: OpenSSL/3.5.7: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Recent curl releases insert the TLS library version after "SSL_read: " (for example "OpenSSL/3.5.7: "). OpenSSL 1.1.1 did not report this condition this way; on 1.1.1 the same truncation usually shows as "curl: (18) transfer closed with N bytes remaining to read".
curl (OpenSSL 3 backend) — CURLE_RECV_ERROR, SSL_R_UNEXPECTED_EOF_WHILE_READING
What it means
The TLS connection was established and data was flowing, then the peer closed the TCP connection without first sending TLS close_notify, while curl still expected more data. OpenSSL 3 reports such an abrupt end as an error instead of a normal end of stream, because a missing close_notify is how a truncation attack looks. curl reports it as a receive failure (exit code 56).
Why it happens
The server process died or timed out mid-response
commonAn application worker killed by a timeout or out-of-memory condition, a PHP-FPM or Gunicorn worker restart, or an upstream that gave up drops the socket while the response body is still being sent.
A middlebox dropped the connection
commonFirewalls, NAT gateways, corporate proxies and load balancers that enforce idle or maximum-duration limits can tear down a long download or a slow response at the TCP level, with no TLS shutdown from the server.
The server ends responses without close_notify
occasionalSome embedded web servers, old IIS versions and hand-written TLS servers close the socket without a TLS shutdown. With HTTP responses that are delimited by connection close, OpenSSL 3 clients report every such response as this error.
A body size limit aborted the transfer
occasionalUpload limits (client_max_body_size, WAF rules) or download quotas sometimes reset the connection instead of returning a proper 413 or 403 response.
How to fix it
- 1.
Find out which hop closes the connection
Note how many bytes and how many seconds pass before the error, then repeat the request directly to the backend. A cut at a round number of seconds points to a timeout in a proxy or load balancer.
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.
Raise the timeout that fires
Increase the limit in the component that cuts the connection above the longest legitimate response time, or make the slow endpoint respond faster (stream or paginate large 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.
Retry idempotent transfers
For downloads over unreliable links, let curl retry and resume. This treats the symptom on the client while the server side is investigated.
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.
Server code: close TLS connections properly
Send close_notify before closing the socket (SSL_shutdown in OpenSSL, unwrap() in Python, Close() on a Go tls.Conn), and delimit HTTP bodies with Content-Length or chunked encoding so a clean end is unambiguous.
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()
Related errors
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)