Pular para o conteúdo
ecdsa.com
curl (OpenSSL 3 backend)curl

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

Como corrigir

  1. 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. 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. 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. 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

Ver toda a base de erros de assinatura