Перейти к основному содержимому

Руководства / Починка: руководства по ошибкам, которые встречаются на практике

ERR_HTTP2_PROTOCOL_ERROR: причины и решения

ERR_HTTP2_PROTOCOL_ERROR означает, что браузер и сервер успешно согласовали HTTP/2, но конкретный фрейм или поток в обмене нарушил правила протокола, и соединение было сброшено. Это отличается от сбоя TLS: зашифрованное соединение сработало, а проблема находится на уровень выше - в том, как был сформирован сам поток HTTP/2.

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

HTTP/2 отправляет запросы и ответы в виде бинарных фреймов через одно соединение, со строгими правилами по размеру фрейма, кодированию заголовков (HPACK) и состоянию потока. Сервер, прокси или CDN, отправляющий некорректный фрейм, слишком большой заголовок либо фрейм для уже закрытого потока, нарушает эти правила, и клиент разрывает соединение, вместо того чтобы гадать, что имелось в виду. Поскольку сбой может возникнуть на сервере приложения, на промежуточном прокси, на edge-узле CDN или в собственном сетевом стеке браузера, эта ошибка охватывает более широкий диапазон первопричин, чем большинство прочих в этом списке.

Как проявляется ошибка

Chrome и Edge показывают "This page isn't working - ERR_HTTP2_PROTOCOL_ERROR", иногда только при некоторых загрузках страницы, а не при других, что является намеком, что сбой скорее непостоянный, чем фиксированная неправильная настройка. Firefox обычно показывает общую ошибку соединения, не называя протокол.

curl может принудительно использовать HTTP/2 и показать точно, на каком фрейме соединение провалилось:

curl --http2 -v https://example.com/ 2>&1 | tail -20
...
* Recv failure: Connection reset by peer
* HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

Сравнение этого с запросом по HTTP/1.1 к тому же URL изолирует, специфична ли проблема для протокола:

curl --http1.1 -sI https://example.com/

Если запрос по HTTP/1.1 проходит успешно, а по HTTP/2 - нет, неисправность в том, как что-то в цепочке реализует HTTP/2, а не в самом приложении.

Что вызывает ERR_HTTP2_PROTOCOL_ERROR

  • Некорректные или слишком большие заголовки от приложения или прокси. Очень длинная cookie, слишком большой набор заголовков ответа либо значение заголовка, содержащее символы, которые HPACK не может закодировать, нарушит размер фрейма, ожидаемый сервером или клиентом.
  • Обратный прокси или балансировщик нагрузки с багованной или устаревшей реализацией HTTP/2. У некоторых старых стеков HTTP/2 в nginx, Apache или встроенных устройствах есть известные проблемы с определенными последовательностями фреймов под нагрузкой.
  • Баг на edge-узле CDN или несовпадение протоколов между edge и origin. Участок браузер-edge и участок edge-origin могут использовать разные протоколы; баг в преобразовании между ними иногда порождает эту ошибку только для определенных форм запроса.
  • Антивирусное ПО или расширение браузера, перехватывающее трафик HTTPS. Тот же класс ПО, что вызывает сбои рукопожатия SSL, может также сломать здоровый поток HTTP/2, если его слой перехвата неправильно говорит на HTTP/2.
  • Устаревший браузер со старой реализацией HTTP/2, либо поврежденный сетевой кэш браузера.
  • Несовпадение Content-Length за обратным прокси. Если nginx (или другой прокси) пересылает ответ, заявленный Content-Length которого не совпадает с реально отправленными байтами, фреймирование HTTP/2 ниже по цепочке может сломаться на полпути.

Как понять, кто виноват

Запустите HTTP-проверку из нескольких мест: если сбой стабилен повсюду, причина в том, как сервер или CDN обрабатывает HTTP/2. Если он падает только у вас, гораздо вероятнее, что причина локальна - браузер, антивирус либо сетевое устройство между вами и сайтом.

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

Если вы посетитель

  1. Перезагрузите страницу. Поскольку причиной часто является единичный некорректный фрейм, а не постоянная неправильная настройка, новое соединение часто проходит успешно.
  2. Очистите кэш браузера на странице chrome://settings/clearBrowserData, поскольку поврежденный закэшированный ресурс может вызвать это при перезагрузке.
  3. Временно отключите сканирование HTTPS/SSL в антивирусе и повторите попытку; этот класс ПО - частая и часто упускаемая из виду причина.
  4. Попробуйте окно инкогнито, чтобы исключить расширение.
  5. Обновите браузер до последней версии, поскольку у более старых клиентских реализаций HTTP/2 были известные баги.

Если вы администрируете сайт

  1. Сравните HTTP/2 с HTTP/1.1 с помощью команд curl выше. Если проваливается только HTTP/2, проблема в слое HTTP/2 у прокси или CDN, а не в самом приложении.
  2. Повысьте лимиты размера заголовков в nginx, если задействованы крупные cookie или заголовки:
    http2_max_field_size 16k;
    http2_max_header_size 32k;
    large_client_header_buffers 4 16k;
    Перезапустите или перезагрузите nginx после изменения и повторите тест.
  3. Проверьте на предмет несовпадения Content-Length между тем, что отправляет приложение, и тем, что пересылает прокси; включите буферизацию прокси (proxy_buffering on;), чтобы nginx мог прочитать полный ответ, прежде чем фреймировать его для HTTP/2.
  4. Обновите nginx, Apache или любой балансировщик нагрузки до актуальной версии; баги обработки фреймов HTTP/2 - именно то, что чинится в точечных релизах.
  5. Отключите HTTP/2 в качестве диагностического теста, а не постоянного решения: временно уберите http2 из директивы listen в nginx. Если ошибки прекратятся, это подтвердит, что неисправность именно в слое HTTP/2, и вы сможете снова его включить после исправления заголовков или буферизации выше.
  6. Проверьте логи на стороне CDN, если он стоит перед origin; большинство CDN показывают ошибки фреймирования HTTP/2 в своих edge-логах гораздо подробнее, чем когда-либо покажет браузер.

Похожие ошибки

  • ERR_SSL_PROTOCOL_ERROR выглядит похоже, но проваливается раньше, во время TLS-рукопожатия, еще до того, как вообще произошел обмен каким-либо фреймом HTTP/2.
  • Коды ошибок сервера 5xx охватывают случаи, где соединение и протокол работают нормально, а проваливается само приложение.

Одну деталь стоит отделить особо: ошибка протокола HTTP/2 - это не то же самое, что поток HTTP/2, штатно сброшенный самим приложением, например когда клиент отменяет запрос на полпути. Инструменты разработчика в браузере и логи доступа сервера иногда помечают оба случая как "reset", но только настоящее нарушение фреймирования порождает ERR_HTTP2_PROTOCOL_ERROR в браузере; намеренно отмененный поток просто останавливается без страницы ошибки.

Как предотвратить ERR_HTTP2_PROTOCOL_ERROR

Поскольку эта ошибка часто непостоянна и привязана к конкретным размерам заголовков или конкретным версиям прокси, она может затрагивать часть посетителей неделями, прежде чем кто-то заметит закономерность. HTTP-проверка, запускаемая по расписанию из нескольких мест, ловит растущую долю сбоев сразу после деплоя, изменения CDN или обновления прокси, вместо того чтобы полагаться на разрозненные жалобы пользователей. HostTracker оповещает по email, SMS, голосовым звонком, через Slack, Telegram и другие каналы, как только проверка начинает проваливаться.

Часто задаваемые вопросы

Это то же самое, что ошибка SSL?

Нет. Эта ошибка происходит уже после успешного TLS, на уровне фреймирования HTTP/2. Ошибка SSL означает, что само зашифрованное соединение вообще не сформировалось.

Почему ошибка появляется только иногда, а не при каждой загрузке страницы?

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

Навредит ли производительности отключение HTTP/2 на моем сервере?

HTTP/2 дает реальные преимущества (мультиплексирование, сжатие заголовков), так что относитесь к его отключению как к временному диагностическому шагу, а не постоянному решению. Исправьте лежащую в основе проблему с размером заголовков или буферизацией и включите его снова.

Может ли это вызвать CDN, даже если мой origin-сервер в порядке?

Да. Edge-узел CDN и origin могут использовать разные протоколы на каждом участке соединения, и баг или неправильная настройка в том, как CDN преобразует между ними, может породить эту ошибку независимо от здоровья самого origin.

Происходит ли это на сайтах, работающих по HTTP/1.1?

Нет, ERR_HTTP2_PROTOCOL_ERROR специфична для соединений, согласовавших HTTP/2. Сайт, отдающий только HTTP/1.1, не может дать именно эту ошибку, хотя может иметь собственные проблемы с соединением.

Проверить сейчас

Запустите бесплатную проверку своего сайта - аккаунт не нужен.

HTTP check

Следить за этим постоянно

Получайте оповещение в момент сбоя: HostTracker проверяет более чем из 300 локаций и уведомляет по email, SMS, в Slack, Telegram и не только.

Возможности HostTracker

Ещё в этом разделе: Починка: руководства по ошибкам, которые встречаются на практике