err_http2_protocol_error: causas e soluções no Chrome

Publicado:

15 min de leitura

Acar Diveroli
Autor: Acar Diveroli
Grade em perspectiva desabando em um funil sob um cubo com núcleo azul; uma linha cortada em uma pequena cruz vermelha

Você abre um aplicativo web, a página de pagamento de uma loja ou a página de um serviço de vídeo no Chrome e recebe uma tela cinza no lugar: "Não é possível acessar esse site", uma linha dizendo que a página "pode estar temporariamente indisponível ou pode ter sido movida permanentemente para um novo endereço da Web" e, no final, ERR_HTTP2_PROTOCOL_ERROR. Às vezes a página carrega pela metade, falta um script ou uma imagem, e o console do desenvolvedor mostra "Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR".

O código aponta para o HTTP/2, o protocolo que a maioria dos sites seguros usa com o Chrome, e quase sempre significa que o site, ou um dispositivo entre você e ele, enviou algo que quebra as regras do HTTP/2. A seguir: o que o código significa, como uma requisição quebra, as causas que reproduzimos, as soluções para visitantes, o que os donos de site verificam no nginx, no IIS e na Cloudflare, e o erro em Go, Node.js e Python.

O que significa ERR_HTTP2_PROTOCOL_ERROR?

Significa que a conexão HTTP/2 entre o seu navegador e o site recebeu algo que o protocolo não permite, e a requisição não pôde ser concluída. O HTTP/2 é a segunda versão principal do HTTP; ele roda dentro de uma conexão criptografada com TLS na porta TCP 443, e o servidor o escolhe durante o handshake TLS com o identificador h2. O Chrome e o Edge são construídos sobre o Chromium, cuja lista de erros de rede define esse código como o erro -337 com uma única linha: "There is an HTTP/2 protocol error." (Há um erro de protocolo HTTP/2.)

Essa linha nomeia o sintoma, não o culpado. O padrão HTTP/2 usa PROTOCOL_ERROR como código genérico para os casos em que "um código de erro mais específico não está disponível", então a mensagem diz que uma regra foi quebrada sem dizer qual. O irmão dele, ERR_QUIC_PROTOCOL_ERROR, diz respeito ao HTTP/3 sobre QUIC e UDP, com causas diferentes, e está explicado em Como resolver err_quic_protocol_error no Chrome e Edge.

O que a página de erro diz a você?

Linha na telaO que significa
"Não é possível acessar esse site"O título geral do Chrome para uma requisição que falhou antes de uma página poder ser exibida
"A página example.com pode estar temporariamente indisponível ou pode ter sido movida permanentemente para um novo endereço da Web."Uma frase padrão, não um diagnóstico; o site geralmente está no ar
ERR_HTTP2_PROTOCOL_ERRORA única informação concreta da página

Vimos essas linhas na tela no Chromium 145. A página não tem a lista "Tente:" nem botão de recarregar: o Chromium não tem um texto próprio para erros de HTTP/2 e recorre à página genérica. O Edge mostra o mesmo código; os outros códigos que aparecem sob esse título estão explicados em Não é possível acessar esse site: o que é e por que acontece.

Quando a conexão quebra depois que o servidor já enviou um cabeçalho 200 OK, a página pode aparecer incompleta e o console do desenvolvedor (F12) registra "Failed to load resource: net::ERR_HTTP2_PROTOCOL_ERROR" para a requisição que foi cortada. Um 200 ao lado do erro significa exatamente isso: a resposta tinha começado antes de o stream ser redefinido.

Como uma requisição HTTP/2 quebra?

  1. A conexão começa. O Chrome abre uma conexão TLS para a porta 443 e oferece h2; o servidor aceita, e os dois lados trocam um frame SETTINGS com os seus limites.
  2. As requisições viajam como streams. Cada requisição ganha o próprio stream (fluxo) na conexão compartilhada, levando frames HEADERS para os cabeçalhos e frames DATA para o corpo.
  3. Um frame quebra uma regra. A RFC 9113, o padrão do HTTP/2, chama uma mensagem de malformada quando o Content-Length não é igual ao total dos frames DATA, quando o valor de um cabeçalho começa ou termina com um espaço, ou quando um cabeçalho específico da conexão, como Connection ou Transfer-Encoding, está presente.
  4. O endpoint que percebe redefine o stream. Uma mensagem malformada deve ser tratada como um erro de stream do tipo PROTOCOL_ERROR, então o endpoint (uma das pontas da conexão) envia um frame RST_STREAM; um erro que corrompe a conexão inteira vira um frame GOAWAY, e a conexão é fechada.
  5. O Chrome reporta -337. Quando o Chrome recebe um RST_STREAM com PROTOCOL_ERROR, ou detecta por conta própria um frame inválido, ele faz essa requisição falhar com ERR_HTTP2_PROTOCOL_ERROR. O Chromium não tenta de novo nem volta para o HTTP/1.1; só o código HTTP_1_1_REQUIRED faz o Chrome reenviar uma requisição pelo protocolo mais antigo.

O que causa ERR_HTTP2_PROTOCOL_ERROR?

CausaSinal típicoQuem corrige
O aplicativo do site envia uma resposta que quebra as regras do HTTP/2: um cabeçalho proibido, um Content-Length errado, um valor de cabeçalho com espaço no finalUm site ou uma página, todos os visitantesO dono do site
Uma CDN ou um proxy reverso rejeita a resposta malformada da origem e redefine o seu streamFalha pela CDN, funciona a partir da origemO dono do site
Cabeçalhos de resposta acima do limite de um servidor ou de uma CDN, geralmente por cookies enormesUm site, depois de fazer loginO dono; excluir os dados do site ajuda na hora
Uma implementação de HTTP/2 antiga ou mal configurada no servidorUm site, muitas vezes logo depois de ativar o HTTPSO dono do site
Software de segurança, um firewall ou um filtro que inspeciona o TLS e altera os framesMuitos sites, em um computador ou em uma redeVocê, ou a equipe de TI
Uma VPN ou um aplicativo de "proteção" que roteia o tráfego por si mesmoSó enquanto o aplicativo está rodandoVocê

No nosso servidor HTTP/2 de teste, o Chromium 145 tolerou um Content-Length maior que o corpo e até exibiu a página truncada, enquanto o cliente HTTP/2 do Node.js, o httpx do Python e o undici rejeitaram a mesma resposta com PROTOCOL_ERROR; quando o próprio servidor redefiniu o stream, o Chromium mostrou ERR_HTTP2_PROTOCOL_ERROR na hora. Esse é o padrão comum no mundo real: uma resposta levemente quebrada que o navegador engoliria é recusada por uma CDN ou um balanceador de carga mais rigoroso na frente do site, que redefine o stream do visitante.

Como resolver como visitante?

Se outros sites seguros também falham, a causa está do seu lado; se o site também falha no seu celular com o Wi-Fi desligado, a causa é do site. Recarregue a página depois de cada passo.

  1. Recarregue uma vez. No canto superior esquerdo, selecione Recarregar esta página.
  2. Tente uma janela anônima ou outro navegador. Abra Mais > Nova janela anônima; se a página carregar ali, desative as extensões uma por uma em Mais > Extensões > Gerenciar extensões.
  3. Desconecte a VPN e os aplicativos de filtragem, incluindo aplicativos que bloqueiam anúncios roteando o tráfego por si mesmos.
  4. Pause a proteção web do antivírus para um teste. Programas que verificam o tráfego HTTPS ficam dentro da conexão criptografada. Desligue só esse recurso, recarregue uma vez e ligue de novo; se a pausa ajudou, atualize o programa.
  5. Exclua os dados salvos do site. Selecione Mais > Configurações, depois Privacidade e segurança > Cookies de terceiros > Ver todos os dados e as permissões do site, pesquise o site, selecione Excluir e confirme com Excluir.
  6. Atualize o Chrome. Selecione Mais > Ajuda > Sobre o Google Chrome e depois Reiniciar, se aparecer.
  7. Em uma rede do trabalho ou da escola, fale com a equipe de TI. Um firewall que inspeciona o tráfego pertence à organização, e a solução também.

No Android, atualize o Chrome pela Play Store: toque no ícone do perfil, depois em Gerenciar apps e dispositivos e, em "Atualizações disponíveis", toque em Atualizar ao lado do Chrome. Para remover os dados salvos, abra o Chrome, toque em Mais > Excluir dados de navegação, escolha os tipos de dados e toque em Excluir dados. Alterne entre Wi-Fi e dados móveis e desligue qualquer aplicativo de VPN antes de culpar o site.

Se o site é seu: como encontrar a resposta quebrada

  1. Localize a requisição. No DevTools, abra o painel Rede, recarregue e encontre a requisição marcada como falha com esse erro; a coluna Protocolo, ativada com um clique com o botão direito no cabeçalho da tabela, mostra h2.
  2. Peça duas vezes pela linha de comando. curl --http2 -v https://example.com/caminho e curl --http1.1 -v com a mesma URL forçam os dois protocolos e imprimem os cabeçalhos da resposta. Se o HTTP/2 falha enquanto o HTTP/1.1 retorna a página, a resposta quebra uma regra do HTTP/2. O curl que vem com o Windows 11 rejeita --http2 ("the installed libcurl version does not support this"), então teste no Linux, no macOS ou no servidor.
  3. Compare a origem com a borda. Atrás de uma CDN ou de um balanceador de carga, peça a mesma URL diretamente ao servidor de origem e pelo endereço público, e compare os cabeçalhos: Content-Length e Content-Encoding, qualquer cabeçalho Connection, Keep-Alive ou Transfer-Encoding, e valores com espaços no final.
  4. Corrija a resposta, não o protocolo. Um middleware de compressão que aplica gzip ao corpo depois que o aplicativo já definiu o Content-Length é a causa clássica; deixe uma única camada comprimir e recalcular o tamanho. Remova os cabeçalhos específicos da conexão do código do aplicativo e mantenha os cookies pequenos. Desligar o HTTP/2 no servidor é um passo de diagnóstico de alguns minutos, nunca a correção: a resposta continua malformada e o próximo cliente rigoroso falha de novo.
  5. nginx. As versões atuais ativam o HTTP/2 com http2 on; ao lado de listen 443 ssl;, disponível desde a 1.25.1; a forma antiga listen 443 ssl http2; está obsoleta, e http2_max_field_size e http2_max_header_size deixaram de valer desde a 1.19.7, substituídas por large_client_header_buffers, como explica a documentação do ngx_http_v2_module.
  6. IIS. O IIS 10 no Windows Server 2016 e posteriores só fala HTTP/2 sobre TLS e volta para o HTTP/1.1 na autenticação do Windows, segundo o artigo da Microsoft sobre HTTP/2 no IIS; o campo "Protocol version" em Logging (Registro) > Select Fields (Selecionar campos) mostra quais requisições usam HTTP/2. Para testar, o Windows pode desligar o HTTP/2 por vinculação TLS com netsh http update sslcert ... disablehttp2=enable (da documentação do netsh http; não testamos aqui).
  7. Cloudflare. O HTTP/2 vem ativado por padrão em todos os planos, e a página sobre HTTP/2 da Cloudflare aponta cabeçalhos de origem com formato incorreto e problemas de compressão, como gzip sem um Content-Length atualizado, como as causas comuns nos sites que passam pelo proxy dela, e sugere deixar a Cloudflare comprimir.

Desenvolvedores e scrapers: o mesmo erro em Go, Node.js e Python

Clientes HTTP que negociam h2 falham do mesmo jeito que o Chrome. O http.Server e o http.DefaultTransport do Go usam HTTP/2 automaticamente para HTTPS (GODEBUG=http2client=0 desliga o lado do cliente). No Node.js 24.22, o fetch embutido falou HTTP/1.1 com o nosso servidor de teste, enquanto um Agent do undici criado com allowH2: true negociou HTTP/2. No Python, o httpx precisa de pip install httpx[http2] e httpx.Client(http2=True); o HTTP/2 vem desligado por padrão. Diante de uma resposta cujo Content-Length prometia 100 bytes mas entregava 5, os nossos clientes reportaram:

text
# Node.js 24.22, node:http2
response: :status=200 content-length=100 content-type=text/plain
stream error: ERR_HTTP2_STREAM_ERROR Stream closed with error code NGHTTP2_PROTOCOL_ERROR

# undici 7.30 com allowH2: true
TypeError: terminated <- ERR_HTTP2_STREAM_ERROR: Stream closed with error code NGHTTP2_PROTOCOL_ERROR

# Python httpx 0.28 com http2=True
h2.exceptions.InvalidBodyLengthError: InvalidBodyLengthError: Expected 100 bytes, received 5

Trate um erro de protocolo HTTP/2 como uma resposta malformada, não como um bloqueio: tente de novo uma vez por HTTP/1.1 para confirmar, corrija o servidor se ele for seu e informe a URL e os cabeçalhos ao dono se não for. Trocar de endereço IP não adianta nada; todo endereço recebe a mesma resposta quebrada.

Um proxy raramente entra em cena. Para um site https://, o cliente pede ao proxy um túnel com uma requisição CONNECT e roda o TLS, com o HTTP/2 dentro dele, de ponta a ponta com o site; o proxy nunca vê um frame, então os Proxies HTTPS não causam nem resolvem esse erro. Só um proxy que encerra o TLS de propósito, como um gateway de inspeção corporativo, é um endpoint HTTP/2 por si só.

Uma segunda saída separa uma falha global de uma regional: repita a requisição a partir dos Proxies de datacenter em outro país; o mesmo erro lá significa que a resposta está quebrada para todo mundo, e uma resposta limpa aponta para a sua própria rede ou para o seu software de inspeção.

Erros relacionados

CódigoNúmeroO que significa
ERR_HTTP2_PROTOCOL_ERROR-337Uma regra do HTTP/2 foi quebrada; a requisição foi cancelada
ERR_HTTP2_SERVER_REFUSED_STREAM-351O servidor recusou o stream antes de processá-lo; o Chrome pode tentar de novo
ERR_HTTP_1_1_REQUIRED-365O servidor pediu HTTP/1.1; o Chrome reenvia a requisição por ele
ERR_QUIC_PROTOCOL_ERROR-356A conexão HTTP/3 sobre QUIC quebrou

Se em vez disso você vê ERR_SSL_PROTOCOL_ERROR, o HTTP/2 nunca chegou a ser alcançado; Como resolver err_ssl_protocol_error no Chrome e Edge cobre esse caso.

Onde você pode encontrar esse erro

  • Aplicativos web atrás de uma CDN ou de um balanceador de carga, em que uma resposta da API carrega um cabeçalho adicionado à mão.
  • Aplicativos ASP.NET e outros hospedados no IIS pouco depois de ativar o HTTPS, já que o HTTP/2 no IIS só existe sobre TLS.
  • Páginas de serviços de vídeo em que as requisições do player falham enquanto o resto da página carrega.

Erros comuns

  • Limpar o cache inteiro do navegador de novo e de novo. Só os cookies do site que falha importam, e só quando a causa são cabeçalhos grandes demais.
  • Acertar o relógio do sistema. Uma data errada produz avisos de certificado, não esse código.
  • Desligar o QUIC em chrome://flags. Essa opção diz respeito ao HTTP/3; o HTTP/2 não tem chave no Chrome.
  • Rotacionar endereços IP em um scraper. A resposta está quebrada para todos os endereços.

Guia de decisão

Sua situaçãoO que fazer
Um site falha em todos os dispositivos e redesO site ou a CDN dele; avise o dono e envie a URL que falha
Muitos sites falham em um computadorExtensões, depois a proteção web do antivírus, depois aplicativos de VPN ou de filtragem
Só uma rede mostra o erroInspeção de TLS nessa rede; pergunte a quem a administra
A página carrega pela metade com erros no consoleO servidor redefiniu um stream depois de um 200; o dono precisa verificar essa resposta
Seu site, atrás da Cloudflare ou de um balanceador de cargaCompare os cabeçalhos e o Content-Length da origem com os da borda

Perguntas frequentes

Como resolver ERR_HTTP2_PROTOCOL_ERROR no Android?

Atualize o Chrome pela Play Store, alterne entre Wi-Fi e dados móveis e desligue qualquer aplicativo de VPN ou de bloqueio de anúncios. Se o site continuar falhando nos dados móveis, a causa é o site ou a CDN dele.

Por que o log do meu servidor mostra 200 OK enquanto os visitantes veem o erro?

Porque a linha de status foi enviada e registrada antes de o stream ser redefinido. O aplicativo respondeu com 200, e depois o servidor, uma CDN ou o navegador achou o resto da resposta malformado e cancelou o stream.

O erro acontece mais em sites com Cloudflare?

Ele fica mais visível ali, porque a borda da Cloudflare é um endpoint HTTP/2 rigoroso entre a origem e o visitante. Uma resposta que um navegador talvez tolerasse direto da origem é rejeitada na borda.

Dá para desligar o HTTP/2 no Chrome?

Não. As configurações do Chrome não têm chave de HTTP/2, e a opção do QUIC em chrome://flags diz respeito ao HTTP/3. Teste do lado do servidor com curl --http1.1 e curl --http2; do lado do cliente, o Firefox é a segunda opinião mais rápida.

ERR_HTTP2_PROTOCOL_ERROR é sinal de que meu computador foi hackeado?

Geralmente não; a maioria dos casos leva ao servidor do site, à CDN dele ou ao software de segurança no seu computador.

Uma VPN ou um proxy resolve ERR_HTTP2_PROTOCOL_ERROR?

Não quando a resposta do site está quebrada, porque os mesmos frames chegam até você por qualquer caminho. Uma VPN ou um proxy que inspeciona é mais vezes a causa do que a cura.

Em resumo

ERR_HTTP2_PROTOCOL_ERROR significa que um frame na conexão HTTP/2 do Chrome quebrou as regras do protocolo, na maioria das vezes porque o site ou a CDN dele redefiniu uma requisição depois de uma resposta malformada: um cabeçalho proibido, um Content-Length que não batia mais com um corpo comprimido ou cabeçalhos grandes demais. Os visitantes testam a janela anônima, outro navegador e uma VPN ou um antivírus pausados; os donos comparam a resposta por HTTP/1.1 e HTTP/2 e a corrigem em vez de desligar o HTTP/2. Para verificações de vários locais, os tipos de proxy estão comparados na nossa página de proxies.