Nginx: client sent invalid chunked body — Причины и решение ошибки 400
Клиентские приложения при отправке потоковых данных (Streaming Upload, multipart POST) получают ответ 400 Bad Request. В системном журнале error.log Nginx фиксируется синтаксический сбой входящего HTTP-потока: client sent invalid chunked body while reading client request body, client: ..., request: "POST /upload HTTP/1.1".
| Причина сбоя | Что отправил клиент | Ожидание Nginx |
|---|---|---|
| Неверный размер чанка | Невалидное Hex-число в заголовке блока | Шестнадцатеричный размер блока (например, 1F4\r\n) |
| Обрыв чанка | TCP FIN до передачи объявленного объема | Полный блок данных заявленной длины |
| Отсутствие терминатора | Завершение потока без 0\r\n\r\n | Финальный нулевой чанк завершения сессии |
- Сбой воспроизводится только на определенных версиях HTTP-клиентов или при нестабильном сетевом соединении (Mobile 3G/LTE).
- Сервер сбрасывает соединение со статусом 400 до передачи запроса в бэкенд.
- Проверьте проблемные запросы в
access.logи сопоставьте их с сетевыми клиентами (User-Agent):grep " 400 " /var/log/nginx/access.log | grep -i "upload" - Убедитесь, что клиентское ПО формирует корректную структуру Chunked Framing согласно RFC 7230:
# Пример валидного формата: <HEX_SIZE>\r\n <DATA>\r\n 0\r\n \r\n - Если клиенты работают по нестабильным каналам связи, увеличьте время ожидания чтения тела запроса:
client_body_timeout 60s; client_header_timeout 60s; - Увеличьте буфер чтения тела запроса для предотвращения дефрагментации блоков:
client_body_buffer_size 128k; - Примените конфигурацию:
sudo nginx -s reload.
tcpdump -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' для детального анализа шестнадцатеричных байтов чанка.Частые вопросы (FAQ)
Что такое Chunked Transfer Encoding в теле запроса?
Это механизм передачи данных, при котором клиент отправляет тело запроса частями (чанками) неизвестного заранее общего размера, предваряя каждый блок его размером в шестнадцатеричном формате.
Почему Nginx возвращает ошибку 400 вместо 500?
Ошибка 400 Bad Request возвращается потому, что ответственность за нарушение формата HTTP-протокола лежит на клиенте, сформировавшем некорректный поток байтов.
Может ли проксирование через HTTP/2 вызывать этот сбой?
В протоколе HTTP/2 концепция chunked transfer encoding отсутствует (используются DATA-фреймы). Если клиентский шлюз некорректно транслирует h2 в HTTP/1.1 chunked, возникает эта ошибка.
Как клиент должен правильно завершать chunked-запрос?
Клиент обязан отправить чанк нулевого размера '0\r\n' и финальную пустую строку '\r\n'.