O que é a net :: ERR_HTTP2_PROTOCOL_ERROR?

36

Atualmente, estou trabalhando em um site, que aciona um net::ERR_HTTP2_PROTOCOL_ERROR 200erro no Google Chrome. Não sei exatamente o que pode provocar esse erro, só notei que ele aparece apenas ao acessar o site em HTTPS. Não tenho 100% de certeza de que esteja relacionado, mas parece que impede que o javascript seja executado corretamente.

Por exemplo, o seguinte cenário acontece:

  1. Estou acessando o site em HTTPS

  2. Meu feed do Twitter integrado via https://publish.twitter.com não está carregado

  3. Percebo no console o arquivo ERR_HTTP2_PROTOCOL_ERROR

  4. Se eu remover o código para carregar o feed do Twitter, o erro permanecerá

  5. Se eu acessar o site em HTTP, o feed do Twitter aparece e o erro desaparece

O Google Chrome é o único navegador da Web que desencadeou o erro: funciona bem no Edge e no Firefox. (Nota: tentei com o Safari e tenho um kcferrordomaincfnetwork 303erro semelhante )

Eu queria saber se isso poderia estar relacionado ao cabeçalho retornado pelo servidor, já que existe essa menção '200' no erro e uma página 404/500 não está acionando nada.

O problema é que o erro não está documentado. A pesquisa do Google me dá muito poucos resultados. Além disso, notei que ele aparece em lançamentos muito recentes do Google Chrome; o erro não aparece na v.64.X, mas na v.75 + (independentemente do sistema operacional; estou trabalhando no Mac).

Qualquer pista neste momento para investigar seria apreciada com prazer!

Desde já, obrigado.

Tristan


Editar 1: pode estar relacionado ao site OK no Firefox, mas não no Safari (erro 303 do kCFErrorDomainCFNetwork) nem no Chrome (net :: ERR_SPDY_PROTOCOL_ERROR)


Edit 2: Os resultados de investigações adicionais são os seguintes:

  • erro não aparece exatamente na mesma página se o servidor retornar 404 em vez de 2XX
  • erro não aparece no local com um certificado HTTPS
  • erro aparece em um servidor diferente (ambos são OVH), que usa um certificado diferente
  • o erro aparece independentemente da versão do PHP usada, de 5.6 a 7.3 (estrutura usada: Cakephp 2.10)

Edit 3: Conforme solicitado, abaixo está o cabeçalho retornado para o recurso com falha, que é a página da web inteira. Mesmo que o erro seja acionado em cada página com um cabeçalho HTTP 200, essas páginas estão sempre carregando no navegador do cliente, mas às vezes falta um elemento (no meu exemplo, o feed externo do Twitter). Todos os outros ativos na guia Rede têm um retorno bem-sucedido, exceto o documento inteiro. linha que falhou no console

Cabeçalho do Google Chrome (com erro):

Cabeçalho do Chrome

Cabeçalho do Firefox (sem erro):

Cabeçalho do Firefox

Uma curl --head --http2solicitação no console retorna o seguinte sucesso:

HTTP/2 200 
date: Fri, 04 Oct 2019 08:04:51 GMT
content-type: text/html; charset=UTF-8
content-length: 127089
set-cookie: SERVERID31396=2341116; path=/; max-age=900
server: Apache
x-powered-by: PHP/7.2
set-cookie: xxxxx=0919c5563fc87d601ab99e2f85d4217d; expires=Fri, 04-Oct-2019 12:04:51 GMT; Max-Age=14400; path=/; secure; HttpOnly
vary: Accept-Encoding

Edit 4: Tentando ir mais fundo com as ferramentas chrome: // net-export / e https://netlog-viewer.appspot.com está me dizendo que a solicitação termina com um RST_STREAM:

t=123354 [st=5170]    HTTP2_SESSION_RECV_RST_STREAM
                      --> error_code = "2 (INTERNAL_ERROR)"
                      --> stream_id = 1

Pelo que li nesta outra postagem , " No HTTP / 2, se o cliente deseja anular a solicitação, ele envia um RST_STREAM. Quando o servidor recebe um RST_STREAM, ele pára de enviar quadros de dados para o cliente, interrompendo a resposta. (ou o download) .A conexão ainda é utilizável para outras solicitações, e as solicitações / respostas simultâneas com a que foi abortada podem continuar a progredir. [...] É possível que, quando o RST_STREAM viajar de o cliente para o servidor, todo o conteúdo da solicitação está em trânsito e chegará ao cliente, o que a descartará, mas para conteúdos de resposta grandes, o envio de um RST_STREAM pode ter uma boa chance de chegar ao servidor antes de todo o conteúdo da resposta é enviado e, portanto, economiza largura de banda " .

O comportamento descrito é o mesmo que eu posso observar. Mas isso significaria que o navegador é o culpado, e então eu não entenderia por que isso acontece em duas páginas idênticas, uma com cabeçalho 200 e a outra 404 (o mesmo ocorre se eu desativar o JS).

Tristan G
fonte
aboutssl.org/fix-google-chrome-error-err_ssl_protocol_error é um em 110 resultados - #
Jaromanda X
Eu estive aqui, obviamente, e existem apenas respostas relacionadas ao cliente, que não podem ser uma solução.
Tristan G
o erro ocorre em navegadores não-chrome? caso contrário, como não é um problema do lado do cliente (especificamente o navegador Chrum)?
Jaromanda X
11
Provavelmente, cabeçalhos de resposta HTTP malformados. O site inteiro não está carregando? Ou apenas um ou mais ativos? Você pode editar a pergunta para incluir os cabeçalhos de resposta HTTP mostrados na resposta http para um ativo que não carrega ao usar HTTP / 2? E também para o Edge / Firefox, onde funciona?
Barry Pollard
11
Não consegue ver nada de errado lá, então suspeite que não seja a solicitação principal. Também ignore a coisa dos cookies - não é isso. Tente isto para ver se você consegue descobrir t: michalspacek.com/…
Barry Pollard

Respostas:

7

Por várias semanas, eu também fiquei irritado com esse "bug":

net :: ERR_HTTP2_PROTOCOL_ERROR 200

No meu caso, ocorreu em imagens geradas pelo PHP.

Foi no header()nível, e neste em particular:

header ('Content-Length:'. Filesize($cache_file));

Obviamente, ele não retornou o tamanho exato, então eu o apaguei e tudo funciona bem agora.

Portanto, o Chrome verifica a precisão dos dados transmitidos pelos cabeçalhos e, se não corresponderem, falharão.

EDITAR

Eu descobri porque o content-lengthvia filesizeestava sendo calculado incorretamente: a GZIPcompactação está ativa nos arquivos PHP, portanto, excluir o arquivo em questão solucionará o problema. Coloque este código no .htaccess:

SetEnvIfNoCase Request_URI ^ / thumb.php no-gzip -vary

Funciona e mantemos o cabeçalho Content-length.

Xtendo
fonte
11
Ótimo você me salvou !!! Mas ainda não entendi o problema real. No meu caso, o erro ocorre apenas em https, mas não em http.
Nico
Olá @Nico, sim, acho normal, a verificação entre o tamanho anunciado e o do arquivo baixado pelo navegador (Chrome) deve ser feita apenas no protocolo https. Muito feliz que esta solução possa ajudá-lo!
Xtendo
11
De alguma forma, eu consegui usar "Comprimento do Conteúdo" em vez de "Comprimento do Conteúdo". Depois de remover o espaço, funcionou. Obrigado.
Martin Lottering 18/03
Olá @Martin Lottering Muito feliz por trabalhar para você agora! :-)
Xtendo 19/03
6

Não descobri exatamente o que estava acontecendo, mas encontrei uma solução.

O recurso CDN da OVH foi o culpado. Eu o tinha instalado no meu serviço host, mas desativado para o meu domínio porque não precisava dele.

De alguma forma, quando eu o habilito, tudo funciona.

Eu acho que isso força o Apache a usar o protocolo HTTP2, mas o que eu não entendo é que de fato havia uma menção HTTP2 em cada um dos meus cabeçalhos, o que eu presumo que o servidor estava respondendo usando o protocolo correto.

Portanto, a solução para o meu caso muito particular foi ativar a opção CDN em todos os domínios envolvidos.

Se alguém entender melhor o que poderia ter acontecido aqui, fique à vontade para compartilhar explicações.

Tristan G
fonte
a limpeza do cache do CDN funcionou para mim
Varshaan 30/04
4

Encontrei isso porque o servidor http2 fechou a conexão ao enviar uma grande resposta ao Chrome.

Por quê? Porque é apenas uma configuração do servidor http2, chamada WriteTimeout .

um livro
fonte
4

No meu caso, foi - não há espaço em disco no servidor web.

Alex Kalmikov
fonte
interessante, para mim, o servidor da web da frente tinha o disco cheio. parece que o nginx não captura essa situação porque não havia nada perceptível no log.
vchrizz 28/03
3

Tive um problema semelhante, estava recebendo ERR_HTTP2_PROTOCOL_ERROR em uma das solicitações HTTP GET.

Percebi que a atualização do Chrome estava pendente, por isso atualizei o navegador Chrome para a versão mais recente e o erro desapareceu na próxima vez em que reiniciei o navegador.

Jaikumar
fonte
2

Eu tive esse problema ao ter um servidor Nginx que expunha o aplicativo node-js ao mundo externo. O Nginx fez o arquivo (css, js, ...) compactado com gzipe com o Chrome parecia o mesmo.

O problema foi resolvido quando descobrimos que o servidor node-js também está compactando o conteúdo com o gzip. De alguma forma, essa dupla compressão leva a esse problema. O cancelamento da compactação node-js resolveu o problema.

No1Lives4Ever
fonte
6
É interessante ver que várias pessoas já responderam a este post e cada vez que a raiz do problema era algo diferente. Eu acho que esse erro é bastante confuso.
Tristan G
2

Atualmente, este erro está sendo corrigido: https://chromium-review.googlesource.com/c/chromium/src/+/2001234

Mas isso me ajudou, alterando as configurações do nginx:

  • ativando o gzip;
  • add_header 'Cache-Control' 'sem armazenamento, sem cache, deve revalidar, revalidar proxy, idade máxima = 0';
  • expira;

No meu caso, o Nginx atua como um proxy reverso para o aplicativo Node.js.

EduardS
fonte
esta resposta funcionou para mim também. Siga este link docs.nginx.com/nginx/admin-guide/web-server/compression para obter a sintaxe correta
Bhargavi Gopalachar
1

Isso aconteceu comigo quando registrei um novo nome de domínio, por exemplo, "novo", por exemplo.com (novo.exemplo.com). O nome não pôde ser resolvido temporariamente no meu local por algumas horas, enquanto poderia ser resolvido no exterior. Então, usei um proxy para testar o site onde vi net::ERR_HTTP2_PROTOCOL_ERRORno console do Chrome algumas postagens do AJAX. Horas depois, quando o nome poderia ser renomeado localmente, esses erros simplesmente desapareciam.

Acho que a razão para esse erro é que as solicitações AJAX não foram redirecionadas pelo meu proxy, basta visitar um site que não foi resolvido pelo meu resolvedor DNS local.

Dzhuang
fonte
1

Eu enfrentei esse erro várias vezes e isso ocorreu devido à transferência de grandes recursos (maiores que 3 MB) do servidor para o cliente.

Fereydoon Barikzehy
fonte
0

Eu tive o mesmo problema (asp, c # - HttpPostedFileBase) ao postar um arquivo maior que 1 MB (embora o aplicativo não tenha nenhuma limitação para o tamanho do arquivo), para mim a simplificação da classe de modelo ajudou. Se você encontrou esse problema, tente remover algumas partes do modelo e veja se ele ajudará de alguma forma. Parece estranho, mas funcionou para mim.

LV
fonte
0

Estou com esse problema há uma semana, já que estou tentando enviar solicitações DELETE para meu servidor PHP por meio do AJAX. Atualizei recentemente meu plano de hospedagem, onde agora tenho um certificado SSL no meu host que armazena os arquivos PHP e JS. Desde a adição de um certificado SSL, não tenho mais esse problema. Esperando que isso ajude com esse erro estranho.

Matthew Fallon
fonte
0

Também enfrentei esse erro e acredito que pode haver várias razões por trás dele. O meu era que o ARR estava sendo esgotado.

No meu caso, o navegador fazia uma solicitação para um site proxy reverso, onde eu defini minhas regras de redirecionamento e esse site proxy está solicitando o site real. Agora, para grandes dados, estava demorando mais de 2 minutos e 5 segundos e o tempo limite do Application Request Routing para o meu servidor foi definido como 2 minutos. Corrigi isso corrigindo o tempo limite do ARR seguindo as etapas abaixo: 1. Vá para o IIS 2. Clique no nome do servidor 3. Clique em Cache de roteamento de solicitação de aplicativo no painel do meio 4. Clique em Configurações de proxy do servidor no painel direito 5. Aumente o tempo limite 6 Clique em Aplicar

Ankit
fonte
0

No nosso caso, o motivo foi um cabeçalho inválido. Como mencionado no Edit 4:

  • pegue os logs
  • no visualizador, escolha Eventos
  • escolheu HTTP2_SESSION

Procure algo semelhante:

HTTP2_SESSION_RECV_INVALID_HEADER

-> error = "Caractere inválido no nome do cabeçalho."

-> header_name = " charset = utf-8 "

Милан Енев
fonte
0

Minha equipe viu isso em um único arquivo javascript que estávamos servindo. Todos os outros arquivos funcionaram bem. Mudamos de http2volta para http1.1e então ou net::ERR_INCOMPLETE_CHUNKED_ENCODINGou ERR_CONTENT_LENGTH_MISMATCH. Por fim, descobrimos que havia um filtro corporativo (Trustwave) que estava detectando erroneamente um "infoleak" (suspeitamos que ele tenha detectado algo em nosso arquivo / nome de arquivo que se assemelha a um número de segurança social). Fazer com que a empresa ajuste esse filtro resolveu nossos problemas.

adamdport
fonte
0

Tivemos esse problema em páginas com longas seqüências de caracteres Base64. O problema ocorre porque usamos o CloudFlare.

Detalhes: https://community.cloudflare.com/t/err-http2-protocol-error/119619 .

Seção principal da postagem do fórum:

Após mais testes nas guias de navegação anônima em vários navegadores e, depois de fazer as alterações no código de uma imagem BASE64 para uma imagem .png real, o problema nunca aconteceu novamente em QUALQUER navegador. O .png tinha cerca de 500kb antes de se tornar um base64, portanto, o CloudFlare apresenta problemas com grandes linhas de texto na mesma linha (já que base64 é uma cadeia longa) como proxy entre o domínio e o heroku. Como mencionado anteriormente, bater diretamente no Heroku url também nunca aconteceu.

O hack temporário é desativar o HTTP / 2 no CloudFlare.

Espero que alguém possa produzir uma solução melhor que não exija desativar o HTTP / 2 no CloudFlare.

Crashalot
fonte