Mensagem de erro
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Também aparece como
- curl: (56) OpenSSL SSL_read: OpenSSL/3.5.7: error:0A000126:SSL routines::unexpected eof while reading, errno 0
Versões recentes do curl inserem a versão da biblioteca TLS depois de “SSL_read: ” (por exemplo, “OpenSSL/3.5.7: ”). O OpenSSL 1.1.1 não informava essa condição dessa forma; no 1.1.1, o mesmo truncamento costuma aparecer como “curl: (18) transfer closed with N bytes remaining to read”.
curl (OpenSSL 3 backend) — CURLE_RECV_ERROR, SSL_R_UNEXPECTED_EOF_WHILE_READING
O que significa
A conexão TLS foi estabelecida e os dados estavam fluindo, até que o outro lado fechou a conexão TCP sem antes enviar o close_notify do TLS, enquanto o curl ainda esperava mais dados. O OpenSSL 3 informa esse fim abrupto como erro, e não como um fim normal do fluxo de dados, porque a falta de close_notify é exatamente o que se vê em um ataque de truncamento. O curl informa isso como falha de recebimento (código de saída 56).
Por que acontece
O processo do servidor morreu ou esgotou o tempo limite no meio da resposta
comumUm worker da aplicação encerrado por tempo limite ou falta de memória, a reinicialização de um worker do PHP-FPM ou do Gunicorn, ou um upstream que desistiu derrubam o socket enquanto o corpo da resposta ainda está sendo enviado.
Um equipamento intermediário derrubou a conexão
comumFirewalls, gateways NAT, proxies corporativos e balanceadores de carga que impõem limites de inatividade ou de duração máxima podem derrubar um download longo ou uma resposta lenta no nível do TCP, sem nenhum encerramento TLS por parte do servidor.
O servidor encerra respostas sem close_notify
ocasionalAlguns servidores web embarcados, versões antigas do IIS e servidores TLS escritos à mão fecham o socket sem encerrar o TLS. Com respostas HTTP delimitadas pelo fechamento da conexão, clientes com OpenSSL 3 informam cada uma dessas respostas como esse erro.
Um limite de tamanho do corpo abortou a transferência
ocasionalLimites de upload (client_max_body_size, regras de WAF) ou cotas de download às vezes redefinem a conexão em vez de retornar uma resposta 413 ou 403 adequada.
Como corrigir
- 1.
Descobrir qual salto fecha a conexão
Anote quantos bytes e quantos segundos se passam até o erro e repita a requisição diretamente no backend. Um corte em um número redondo de segundos aponta para um tempo limite em um proxy ou balanceador de carga.
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.
Aumentar o tempo limite que está estourando
No componente que corta a conexão, aumente o limite para um valor acima do maior tempo de resposta legítimo, ou faça o endpoint lento responder mais rápido (use streaming ou paginação em exportações grandes).
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.
Repetir transferências idempotentes
Para downloads em conexões instáveis, deixe o curl repetir e retomar a transferência. Isso trata o sintoma no cliente enquanto o lado do servidor é investigado.
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.
Código do servidor: fechar as conexões TLS corretamente
Envie close_notify antes de fechar o socket (SSL_shutdown no OpenSSL, unwrap() no Python, Close() em um tls.Conn do Go) e delimite os corpos HTTP com Content-Length ou codificação chunked para que um fim limpo seja inequívoco.
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()
Erros relacionados
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)