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
- Неправильно сформовані чи завеликі заголовки від застосунку чи проксі. Дуже довга кукі, завеликий набір заголовків відповіді чи значення заголовка із символами, які HPACK не може закодувати, порушать очікуваний сервером чи клієнтом розмір фрейма.
- Зворотний проксі чи балансувальник навантаження із зіпсованою чи застарілою реалізацією HTTP/2. Деякі старіші стеки HTTP/2 у nginx, Apache чи вбудованих пристроях мають відомі проблеми з конкретними послідовностями фреймів під навантаженням.
- Баг edge-вузла CDN чи невідповідність протоколу edge-origin. Ділянка браузер-edge й ділянка edge-origin можуть використовувати різні протоколи; баг у перетворенні між ними іноді дає цю помилку лише для певних форм запитів.
- Антивірусне ПЗ чи розширення браузера, що перехоплює HTTPS-трафік. Той самий клас ПЗ, що спричиняє збої TLS-рукостискання, може також зламати здоровий HTTP/2-потік, якщо його шар перехоплення неправильно говорить HTTP/2.
- Застарілий браузер зі старою реалізацією HTTP/2, чи пошкоджений мережевий кеш браузера.
- Невідповідність
Content-Lengthза зворотним проксі. Якщо nginx (чи інший проксі) пересилає відповідь, чий заявленийContent-Lengthне збігається з фактично надісланими байтами, фреймування HTTP/2 нижче за течією може зламатися посередині.
Як зрозуміти, хто винен
Запустіть HTTP-перевірку з кількох локацій: якщо збій стабільний усюди, винна обробка HTTP/2 на сервері чи CDN. Якщо провалюється лише у вас, набагато ймовірніше, що причина локальна - браузер, антивірус чи мережевий пристрій між вами і сайтом.
Як виправити ERR_HTTP2_PROTOCOL_ERROR
Якщо ви відвідувач
- Перезавантажте сторінку. Оскільки причина часто в одному неправильно сформованому фреймі, а не в стійкій неправильній конфігурації, свіже з'єднання часто спрацьовує успішно.
- Очистіть кеш браузера на
chrome://settings/clearBrowserData, оскільки пошкоджений закешований ресурс може спричинити це при перезавантаженні. - Тимчасово вимкніть сканування HTTPS/SSL в антивірусі і повторіть спробу; цей клас ПЗ - поширена й часто ігнорована причина.
- Спробуйте вікно інкогніто, щоб виключити розширення.
- Оновіть браузер до останньої версії, оскільки старіші клієнтські реалізації HTTP/2 мали відомі баги.
Якщо ви керуєте сайтом
- Порівняйте HTTP/2 з HTTP/1.1 командами curl вище. Якщо провалюється лише HTTP/2, проблема в шарі HTTP/2 проксі чи CDN, а не в застосунку.
- Підвищте ліміти розміру заголовків у nginx, якщо задіяні великі кукі чи заголовки:
Перезапустіть чи перезавантажте nginx після зміни і протестуйте знову.http2_max_field_size 16k; http2_max_header_size 32k; large_client_header_buffers 4 16k; - Перевірте на невідповідність
Content-Lengthміж тим, що надсилає застосунок, і тим, що пересилає проксі; увімкніть буферизацію проксі (proxy_buffering on;), щоб nginx міг прочитати повну відповідь, перш ніж формувати її фрейми для HTTP/2. - Оновіть nginx, Apache чи будь-який балансувальник навантаження до актуальної версії; баги обробки фреймів HTTP/2 - саме той тип речей, що виправляють у точкових релізах.
- Вимкніть HTTP/2 як діагностичний тест, а не постійне виправлення: тимчасово приберіть
http2з директивиlistenу nginx. Якщо помилки припиняться, збій підтверджено саме в шарі HTTP/2, і ви зможете знову увімкнути його, щойно застосуєте виправлення заголовків чи буферизації вище. - Перевірте логи на боці 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 сповіщає електронною поштою, SMS, голосовим дзвінком, у Slack, Telegram та іншими способами, щойно перевірка почне провалюватися.
Часті запитання
Чи ERR_HTTP2_PROTOCOL_ERROR - те саме, що помилка 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, не може дати саме цю помилку, хоча може мати власні проблеми з'єднання.