
Запрос не дошёл. Нет кода статуса, потому что ответ никогда не пришёл. И когда вы ищете в своём логе доступа запрос, который не дошёл, там нет для него строки вообще.
Эта комбинация это подпись сбоя ниже HTTP, и ERR_HTTP2_PROTOCOL_ERROR это самый частый
способ, которым Chrome его сообщает. Стоит десяти минут, потому что почти всё написанное
об этом рекомендует одну и ту же обходную схему, и люди ошибаются, принимая диагноз за
исправление.
Что на самом деле говорит этот код
Список сетевых ошибок Chromium, из которого эти строки генерируются, определяет это в шести словах:
Произошла ошибка протокола HTTP/2.
Это всё, что там есть. Номер это -337, и ничто в нём не называет причину, направление или виновника. Поиск этой строки дал бы тысячу страниц с догадками, потому что сам исходник тоже гадает.
Шесть ошибок, что не расплывчаты, и почему это важно
Вот часть, которую никто не упоминает. У Chromium не одна ошибка HTTP/2. Их несколько, и все остальные конкретны:
-
ERR_HTTP2_SERVER_REFUSED_STREAM, -351, которую исходник описывает подробно: сервер “отказал в запросе без обработки” и сказал об этом, либо кадромGOAWAYс кодом ошибкиNO_ERRORи Last-Stream-ID ниже этого запроса, либоRST_STREAMсREFUSED_STREAM. Комментарий добавляет операционную деталь: “Клиент может повторить (на другом соединении).” -
ERR_HTTP2_PING_FAILED, -352: “HTTP/2 сервер не ответил на сообщение PING.” -
ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY, -360: “Безопасность транспорта недостаточна для версии HTTP/2.” -
ERR_HTTP2_FLOW_CONTROL_ERROR, -361,ERR_HTTP2_FRAME_SIZE_ERROR, -362, иERR_HTTP2_COMPRESSION_ERROR, -363.
Поэтому, когда вы получаете -337 вместо одной из них, вы узнали что-то реальное: это был не
отказ потока, не мёртвое keepalive, не проблема с шифром, не flow control, не размер кадра,
не сжатие заголовков. ERR_HTTP2_PROTOCOL_ERROR это “ничего из вышеперечисленного” в HTTP/2,
и вышеперечисленное это шесть названных вещей, которые вы теперь можете перестать исследовать.
Это меньший результат, чем причина, и это намного лучше, чем ничего, что кажется предлагает само сообщение.
Почему ваши логи пусты
Причина отсутствия строки в логе доступа в спецификации, и стоит её читать, потому что она объясняет и то, почему один пользователь сообщает о нескольких сбоях сразу.
RFC 9113 разделяет два вида сбоя. “Ошибка потока это ошибка, относящаяся к конкретному потоку, которая не влияет на обработку других потоков.” Ошибка соединения это совсем другое: “любая ошибка, которая препятствует дальнейшей обработке уровня кадров или повреждает любое состояние соединения.”
HTTP/2 мультиплексирует. Одно соединение несёт много запросов одновременно, поэтому ошибка соединения не отваливает запрос, который её вызвал. Она отваливает каждый запрос в полёте на этом соединении.
- Что говорит отчёт
- Страница загружалась наполовину, некоторые изображения отсутствуют и одна отправка формы ничего не сделала. Три отдельных бага, поданные отдельно
- Что произошло
- Одна ошибка соединения сбила всё в полёте на этом соединении в один момент. Одна причина, три симптома и никакой код статуса ни на одном из них
И потому что обмен никогда не завершился как HTTP, нечему записываться серверу. Никакой метод, никакой путь, никакой статус. Пользователь видел, что что-то не дошло, а ваши логи показывают зазор, где это должно было быть.
Что безопасно повторять, на что протокол отвечает
Это вопрос, что имеет значение, если платёж или отправка формы была в полёте, и на него есть реальный ответ, а не пожимание плечами.
RFC 9113 говорит, что “конечная точка, которая встречает ошибку соединения, должна сначала
отправить кадр GOAWAY (Section 6.8) с идентификатором потока последнего потока, который она
успешно получила от своего партнёра.”
Этот идентификатор это линия, проведённая через запросы. Всё, пронумерованное выше него, не было получено, что означает, что оно не было обработано, что означает, что повторение его не может дублировать ничего. Это ровно почему собственный комментарий Chromium на отказанный поток говорит, что клиент может повторить на другом соединении.
Подвох в том, что эта информация существует примерно секунду, внутри браузера, а потом она уходит. Её нет в логе вашего сервера, потому что кадры, что её несли, ниже уровня, что ваш сервер логирует.
Session Replay
Бесплатное расширение для Chrome. Один клик на странице, которая ведёт себя не так, захватывает скриншот, консоль и сетевой журнал и отдаёт вам ссылку, которую можно вставить в задачу.
“Отключить HTTP/2” это диагноз, не исправление
Совет, что вы найдёте везде, это отключить HTTP/2 и посмотреть, перестанут ли ошибки. Это хороший совет и его широко неправильно читают.
Если ошибки перестанут, вы узнали, где сидит вина: что-то в слое HTTP/2 между этим пользователем и вами неправильно обрабатывает кадры. Вы не узнали, что HTTP/2 ненадёжен, и вы ничего не исправили. Вы отключили мультиплексирование для каждого посетителя, чтобы обойти чужой баг.
Эта сторона обычно не ваш сервер. Частые причины это то, что сидит в середине: обратный прокси или балансировщик нагрузки со своей собственной реализацией HTTP/2, граница CDN, оборудование корпоративной сети, что обрывает и переустанавливает TLS, и программа безопасности на машине самого пользователя, делающая то же самое. Каждая из них говорит HTTP/2 от вашего имени, и каждая это место, где кадр может быть неправильно сформирован, не делая никто никогда ничего неправильного.
Потому что это часто влияет на один офис, один ISP или один антивирус, и больше на никого.
Что спросить у человека, что это наткнулся
Два вопроса, и второй стоит больше, чем выглядит.
Точная строка из консоли или страницы ошибки. ERR_HTTP2_PROTOCOL_ERROR и
ERR_HTTP2_SERVER_REFUSED_STREAM это разные проблемы с разными ответами, и отчёт, что
говорит “сетевая ошибка”, выбросил в отходы только отличие, что было бесплатно.
Это происходит на другой сети? Если это перестаёт на мобильных данных, причина между ними и вами, а не на вашем сервере, и вы сузили это до их сетевого оборудования в один вопрос. Это тот же тест, что разделяет корпоративный прокси от реальной проблемы с сертификатом на экране connection is not private, и это работает здесь из той же причины.
Что из этого взять
Сообщение расплывчато, потому что расплывчат исходник, и знание об этом мешает вам читать смысл в него, что там не лежит. Что оно вам говорит, это всё, чем оно не является, и шесть названных альтернатив это реальное сужение.
Остальное следует из того, где сидит сбой. Он ниже HTTP, так что нет кода статуса и часто нет строки логе. Это ошибка соединения, так что она берёт с собой несколько запросов и приходит как несколько отчётов о багах. И вещь, что сказала бы вам, безопасен ли повтор, это кадр, что браузер видел и ваш сервер никогда не видел.
Список ошибок Chromium, с определением одной строки каждого, net_error_list.h, и сам протокол это RFC 9113.