Nginx: HTTP/2 PROTOCOL_ERROR in frame header — Причины и решение
Браузер пользователя неожиданно обрывает загрузку сайта с фатальной сетевой ошибкой ERR_HTTP2_PROTOCOL_ERROR. В системном журнале error.log Nginx фиксируется событие: HTTP/2 connection error: PROTOCOL_ERROR detected in frame header, client: ..., server: ... или client sent invalid stream processing frame.
| Тип ошибки | Место сбоя | Причина |
|---|---|---|
PROTOCOL_ERROR | Парсер HTTP/2 фреймов | Клиент или прокси нарушил порядок следования бинарных фреймов (HEADERS/DATA) |
| HPACK Huffman Decompression | Таблица динамических заголовков | Повреждение контекста распаковки сжатых заголовков |
| Промежуточный DPI / WAF | Сетевой уровень | Антивирус или фаервол повредил TLS payload в транзите |
- Страница начинает загружаться, но стили, скрипты или изображения случайно падают с ошибкой протокола.
- В логах Nginx соединение помечается как принудительно закрытое по инициативе конечного автомата HTTP/2.
- Увеличьте лимиты параллельных потоков и размеры входящих фреймов HTTP/2 в
nginx.conf:http { # Увеличиваем размер буфера для одного чанка HTTP/2 фрейма: http2_chunk_size 16k; # Лимит входящих заголовков HTTP/2: http2_max_field_size 32k; http2_max_header_size 64k; # Максимум параллельных стримов в рамках 1 TCP-сессии: http2_max_concurrent_streams 128; } - Убедитесь, что веб-сервер не отдает пустые или дублирующиеся запрещенные заголовки (согласно HTTP/2 запрещены заголовки
Connection,Keep-Alive,Transfer-Encoding):# Бэкенд НЕ должен передавать заголовок Connection в Nginx при работе по HTTP/2 - Если на клиентах включены сетевые экраны/DPI, проверьте корректность размера пакетов MTU на сетевом интерфейсе хоста, исключив фрагментацию пакетов:
sudo ip link set dev eth0 mtu 1500 - Проверьте конфигурацию на ошибки синтаксиса:
sudo nginx -t. - Примените обновленные настройки:
sudo systemctl reload nginx.
Connection, Upgrade, Keep-Alive, Proxy-Connection) признаны грубым нарушением стандарта. Если Nginx или бэкенд возвращает заголовок Connection: keep-alive внутри фрейма HEADERS, браузер Chrome/Firefox обязан сбросить сессию с ошибкой PROTOCOL_ERROR.Частые вопросы (FAQ)
Почему ERR_HTTP2_PROTOCOL_ERROR возникает в Chrome, но сайт открывается по HTTP/1.1?
Потому что парсер HTTP/2 в Chromium крайне строго соблюдает спецификацию RFC 7540. Любая синтаксическая неточность в фрейме или таблице HPACK немедленно приводит к блокировке TCP-соединения.
Что такое таблица динамических заголовков HPACK?
Это механизм сжатия заголовков в HTTP/2: клиент и сервер хранят общую таблицу ранее отправленных заголовков. Если один байт теряется или повреждается, вся последующая расшифровка заголовков ломается, вызывая PROTOCOL_ERROR.
Как временно отключить HTTP/2 для проверки гипотезы?
В директиве listen удалите флаг http2 (или укажите 'http2 off;' в современных версиях Nginx) и перезагрузите веб-сервер.
Могут ли символы перевода строки в Cookie вызывать этот сбой?
Да, наличие скрытых нулевых байтов или некорректных символов в заголовках Cookie часто приводит к сбою декомпрессии HPACK.