Перейти к содержимому
ecdsa.com
curl (OpenSSL 3 backend)curl

Сообщение об ошибке

curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0

Также выводится как

  • curl: (56) OpenSSL SSL_read: OpenSSL/3.5.7: error:0A000126:SSL routines::unexpected eof while reading, errno 0

Последние версии curl вставляют после «SSL_read: » версию TLS-библиотеки (например, «OpenSSL/3.5.7: »). OpenSSL 1.1.1 не сообщал об этой ситуации таким образом: в 1.1.1 то же усечение обычно выглядит как «curl: (18) transfer closed with N bytes remaining to read».

curl (OpenSSL 3 backend) — CURLE_RECV_ERROR, SSL_R_UNEXPECTED_EOF_WHILE_READING

Что это означает

TLS-соединение было установлено и данные передавались, но затем другая сторона закрыла TCP-соединение, не отправив перед этим оповещение TLS close_notify, хотя curl ещё ждал данных. OpenSSL 3 считает такое внезапное завершение ошибкой, а не обычным концом потока, потому что атака усечения выглядит именно так: close_notify не приходит. curl сообщает об этом как о сбое при получении данных (код завершения 56).

Почему это происходит

Как исправить

  1. 1.

    Выясните, какой узел на пути закрывает соединение

    Запишите, сколько байт и сколько секунд проходит до ошибки, затем повторите запрос напрямую к бэкенду. Обрыв на круглом числе секунд указывает на тайм-аут в прокси или балансировщике нагрузки.

    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.

    Увеличьте срабатывающий тайм-аут

    Поднимите лимит в компоненте, который обрывает соединение, выше самого долгого нормального времени ответа или ускорьте медленный эндпоинт (отдавайте большие выгрузки потоком или постранично).

    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.

    Повторяйте идемпотентные передачи данных

    При скачивании по ненадёжным каналам разрешите curl повторять попытки и докачивать данные. Это лечит симптом на стороне клиента, пока причину ищут на стороне сервера.

    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.

    Серверный код: закрывайте TLS-соединения правильно

    Отправляйте close_notify перед закрытием сокета (SSL_shutdown в OpenSSL, unwrap() в Python, Close() у tls.Conn в Go) и обозначайте границы HTTP-тела заголовком Content-Length или кодированием chunked, чтобы штатное завершение было однозначным.

    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()

Связанные ошибки

Открыть всю базу ошибок подписей