À quoi sert net :: ERR_HTTP2_PROTOCOL_ERROR?


36

Je travaille actuellement sur un site Web, ce qui déclenche une net::ERR_HTTP2_PROTOCOL_ERROR 200erreur sur Google Chrome. Je ne sais pas exactement ce qui peut provoquer cette erreur, je viens de remarquer qu'elle n'apparaît que lors de l'accès au site Web en HTTPS. Je ne peux pas être sûr à 100% qu'il est lié, mais il semble qu'il empêche le javascript de s'exécuter correctement.

Par exemple, le scénario suivant se produit:

  1. J'accède au site Web en HTTPS

  2. Mon flux Twitter intégré via https://publish.twitter.com n'est pas du tout chargé

  3. Je peux remarquer dans la console l'ERR_HTTP2_PROTOCOL_ERROR

  4. Si je supprime le code pour charger le flux Twitter, l'erreur persiste

  5. Si j'accède au site Web en HTTP, le fil Twitter apparaît et l'erreur disparaît

Google Chrome est le seul navigateur Web qui déclenche l'erreur: il fonctionne bien sur Edge et Firefox. (NB: j'ai essayé avec Safari, et j'ai une kcferrordomaincfnetwork 303erreur similaire )

Je me demandais si cela pouvait être lié à l'en-tête retourné par le serveur car il y a cette mention '200' dans l'erreur, et une page 404/500 ne déclenche rien.

Le problème est que l'erreur n'est pas documentée du tout. La recherche Google me donne très peu de résultats. De plus, j'ai remarqué qu'il apparaît sur des versions très récentes de Google Chrome; l'erreur n'apparaît pas sur v.64.X, mais elle le fait sur v.75 + (quel que soit le système d'exploitation; je travaille sur Mac tho).

Tout indice à ce stade pour enquêter serait grandement apprécié!

Merci d'avance.

Tristan


Edit 1: Peut être lié au site Web OK sur Firefox mais pas sur Safari (erreur 303 kCFErrorDomainCFNetwork) ni Chrome (net :: ERR_SPDY_PROTOCOL_ERROR)


Edit 2: Les résultats des enquêtes complémentaires sont les suivants:

  • l'erreur n'apparaît pas exactement sur la même page si le serveur renvoie 404 au lieu de 2XX
  • l'erreur n'apparaît pas sur le local avec un certificat HTTPS
  • erreur apparaît sur un autre serveur (les deux sont des OVH), qui utilise un certificat différent
  • l'erreur apparaît quelle que soit la version PHP utilisée, de 5.6 à 7.3 (framework utilisé: Cakephp 2.10)

Edit 3: Comme demandé, ci-dessous est l'en-tête retourné pour la ressource défaillante, qui est la page Web entière. Même si l'erreur se déclenche sur chaque page ayant un en-tête HTTP 200, ces pages se chargent toujours sur le navigateur du client, mais parfois un élément manque (dans mon exemple, le flux Twitter externe). Tous les autres actifs de l'onglet Réseau ont un retour de réussite, sauf le document entier lui-même. ligne qui a échoué dans la console

En-tête Google Chrome (avec erreur):

En-tête Chrome

En-tête Firefox (sans erreur):

En-tête Firefox

Une curl --head --http2demande dans la console renvoie le succès suivant:

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: Essayer d'aller plus loin avec les outils chrome: // net-export / et https://netlog-viewer.appspot.com me dit que la demande se termine par un RST_STREAM:

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

Pour ce que j'ai lu dans cet autre article , " Dans HTTP / 2, si le client veut abandonner la demande, il envoie un RST_STREAM. Lorsque le serveur reçoit un RST_STREAM, il cessera d'envoyer des trames de données au client, arrêtant ainsi la réponse (ou le téléchargement). La connexion est toujours utilisable pour d'autres demandes, et les demandes / réponses qui étaient simultanées à celle qui a été abandonnée peuvent continuer à progresser. [...] Il est possible qu'au moment où le RST_STREAM passe de du client au serveur, tout le contenu de la demande est en transit et arrivera au client, qui le rejettera. Cependant, pour un contenu de réponse volumineux, l'envoi d'un RST_STREAM peut avoir une bonne chance d'arriver au serveur avant le tout. le contenu de la réponse est envoyé et économisera donc de la bande passante. "

Le comportement décrit est le même que celui que je peux observer. Mais cela signifierait que le navigateur est le coupable, et je ne comprendrais pas pourquoi cela se produit sur deux pages identiques, l'une ayant un en-tête 200 et l'autre un 404 (il en va de même si je désactive JS).



Je suis ici, évidemment, et il n'y a que des réponses côté client, ce qui ne peut pas être une solution.
Tristan G

l'erreur se produit-elle dans les navigateurs non-chrome? sinon, en quoi n'est-ce pas un problème côté client (en particulier le navigateur Chrum)?
Jaromanda X

1
Probablement un en-tête de réponse HTTP mal formé. Le site entier ne se charge-t-il pas? Ou juste un ou plusieurs actifs? Pouvez-vous modifier la question pour inclure les en-têtes de réponse HTTP affichés dans la réponse http pour un actif qui ne se charge pas lors de l'utilisation de HTTP / 2? Et aussi pour Edge / Firefox où cela fonctionne?
Barry Pollard du

1
Je ne vois rien de mal là-bas, alors soupçonnez que ce n'est pas la demande principale. Ignorez également les cookies - ce n'est pas ça. Essayez ceci pour voir si vous pouvez comprendre: michalspacek.com/…
Barry Pollard

Réponses:


7

Pendant plusieurs semaines, j'ai également été agacé par ce "bug":

net :: ERR_HTTP2_PROTOCOL_ERROR 200

Dans mon cas, cela s'est produit sur des images générées par PHP.

C'était au header()niveau, et sur celui-ci en particulier:

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

Il n'a évidemment pas retourné la taille exacte, donc je l'ai supprimé et tout fonctionne bien maintenant.

Chrome vérifie donc l'exactitude des données transmises via les en-têtes, et si elles ne correspondent pas, elles échouent.

ÉDITER

J'ai trouvé pourquoi content-lengthvia filesizeétait mal calculé: la GZIPcompression est active sur les fichiers PHP, donc l'exclusion du fichier en question résoudra le problème. Mettez ce code dans .htaccess:

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

Cela fonctionne et nous gardons l'en-tête Content-length.


1
Super tu m'as sauvé !!! Mais je ne comprends toujours pas le vrai problème, dans mon cas, l'erreur ne se produit que dans https mais pas dans http.
Nico

Bonjour @Nico, oui, je pense que c'est normal, la vérification entre la taille annoncée et celle du fichier téléchargé par le navigateur (Chrome) ne doit se faire que dans le protocole https. Très heureux que cette solution puisse vous aider!
Xtendo

1
D'une manière ou d'une autre, j'ai réussi à utiliser "Content -Length" au lieu de "Content-Length". Après avoir supprimé l'espace, cela a fonctionné. Je vous remercie.
Martin Lottering

Bonjour @Martin Lottering Très heureux que cela fonctionne pour vous maintenant! :-)
Xtendo

6

Je n'ai pas compris ce qui se passait exactement, mais j'ai trouvé une solution.

La fonction CDN d'OVH était le coupable. Je l'avais installé sur mon service hôte mais désactivé pour mon domaine car je n'en avais pas besoin.

D'une manière ou d'une autre, lorsque je l'active, tout fonctionne.

Je pense que cela oblige Apache à utiliser le protocole HTTP2, mais ce que je ne comprends pas, c'est qu'il y avait en effet une mention HTTP2 dans chacun de mes en-têtes, ce qui, je suppose, signifie que le serveur répondait en utilisant le bon protocole.

Donc, la solution pour mon cas très particulier était d'activer l'option CDN sur tous les domaines concernés.

Si quelqu'un comprend mieux ce qui aurait pu arriver ici, n'hésitez pas à partager des explications.


purger le cache cdn a fonctionné pour moi
Varshaan

4

J'ai rencontré cela parce que le serveur http2 a fermé la connexion lors de l'envoi d'une grosse réponse au Chrome.

Pourquoi? Parce qu'il s'agit simplement d'un paramètre du serveur http2, nommé WriteTimeout .


4

Dans mon cas, c'était - pas d'espace disque sur le serveur Web.


intéressant, pour moi la même chose, le serveur Web avant avait un disque plein. semble que nginx n'attrape pas cette situation car il n'y avait rien de notable dans le journal.
vchrizz

3

J'ai rencontré un problème similaire, j'obtenais ERR_HTTP2_PROTOCOL_ERROR sur l'une des requêtes HTTP GET.

J'ai remarqué que la mise à jour de Chrome était en attente, j'ai donc mis à jour le navigateur Chrome vers la dernière version et l'erreur a disparu la prochaine fois lorsque j'ai relancé le navigateur.


2

J'ai eu ce problème lors de l'utilisation d'un serveur Nginx qui exposait l'application node-js au monde extérieur. Le Nginx a fait le fichier (css, js, ...) compressé avec gzipet avec Chrome il ressemblait à la même chose.

Le problème a été résolu lorsque nous avons constaté que le serveur node-js compressait également le contenu avec gzip. D'une certaine façon, cette double compression conduit à ce problème. L'annulation de la compression node-js a résolu le problème.


6
Il est intéressant de voir que plusieurs personnes ont déjà répondu à ce message, et à chaque fois la racine du problème était quelque chose de différent. Je pense que cette erreur est assez déroutante.
Tristan G

2

Cette erreur est en cours de correction: https://chromium-review.googlesource.com/c/chromium/src/+/2001234

Mais cela m'a aidé, en modifiant les paramètres de nginx:

  • activer gzip;
  • add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age = 0';
  • expire;

Dans mon cas, Nginx agit comme un proxy inverse pour l'application Node.js.


cette réponse a fonctionné pour moi aussi. Suivez ce lien docs.nginx.com/nginx/admin-guide/web-server/compression pour la syntaxe appropriée
Bhargavi Gopalachar

1

Cela m'est arrivé lorsque j'ai enregistré un nouveau nom de domaine, par exemple, "nouveau" pour example.com (new.example.com). Le nom n'a pas pu être résolu temporairement dans mon emplacement pendant quelques heures, alors qu'il pourrait l'être à l'étranger. J'ai donc utilisé un proxy pour tester le site Web où j'ai vu net::ERR_HTTP2_PROTOCOL_ERRORdans la console chrome pour certains messages AJAX. Quelques heures plus tard, lorsque le nom pouvait être récupéré localement, ces erreurs ont tout simplement disparu.

Je pense que la raison de cette erreur est que ces demandes AJAX n'ont pas été redirigées par mon proxy, il suffit de visiter un site Web qui n'a pas été résolu par mon résolveur DNS local.


1

J'ai rencontré cette erreur plusieurs fois et c'était dû au transfert de grandes ressources (supérieures à 3 Mo) du serveur au client.


0

J'ai eu le même problème (asp, c # - HttpPostedFileBase) lors de la publication d'un fichier qui était supérieur à 1 Mo (même si l'application n'a pas de limitation de taille de fichier), pour moi, la simplification de la classe de modèle a aidé. Si vous rencontrez ce problème, essayez de supprimer certaines parties du modèle et voyez si cela vous aidera de quelque manière que ce soit. Cela semble étrange, mais a fonctionné pour moi.


0

Je rencontre ce problème depuis la semaine dernière maintenant que j'essaie d'envoyer des demandes DELETE à mon serveur PHP via AJAX. J'ai récemment mis à jour mon plan d'hébergement où j'ai maintenant un certificat SSL sur mon hôte qui stocke les fichiers PHP et JS. Depuis l'ajout d'un certificat SSL, je ne rencontre plus ce problème. En espérant que cela aide avec cette étrange erreur.


0

J'ai également fait face à cette erreur et je pense qu'il peut y avoir plusieurs raisons derrière elle. Le mien l'était, ARR était en train d'expiration.

Dans mon cas, le navigateur faisait une demande à un site proxy inverse où j'ai défini mes règles de redirection et ce site proxy demande finalement le site réel. Maintenant, pour les données volumineuses, cela prenait plus de 2 minutes 5 secondes et le délai d'expiration du routage des demandes d'application pour mon serveur a été défini sur 2 minutes. J'ai résolu ce problème en augmentant le délai d'expiration ARR en procédant comme suit: 1. Accédez à IIS 2. Cliquez sur le nom du serveur 3. Cliquez sur Application Request Routing Cache dans le volet central 4. Cliquez sur Server Proxy settings dans le volet droit 5. Augmentez le délai d'expiration 6 Cliquez sur Appliquer


0

Dans notre cas, la raison était un en-tête non valide. Comme mentionné dans Edit 4:

  • prenez les journaux
  • dans la visionneuse, choisissez Événements
  • a choisi HTTP2_SESSION

Recherchez quelque chose de similaire:

HTTP2_SESSION_RECV_INVALID_HEADER

-> error = "Caractère non valide dans le nom de l'en-tête."

-> header_name = " charset = utf-8 "


0

Mon équipe l'a vu sur un seul fichier javascript que nous servions. Tous les autres fichiers ont bien fonctionné. Nous sommes passés de http2dos à http1.1puis soit net::ERR_INCOMPLETE_CHUNKED_ENCODINGou ERR_CONTENT_LENGTH_MISMATCH. Nous avons finalement découvert qu'il y avait un filtre d'entreprise (Trustwave) qui détectait par erreur une "infoleak" (nous soupçonnons qu'il a détecté quelque chose dans notre fichier / nom de fichier qui ressemblait à un numéro de sécurité sociale). Faire en sorte que l'entreprise modifie ce filtre a résolu nos problèmes.


0

Nous avons rencontré ce problème sur les pages contenant de longues chaînes Base64. Le problème se produit car nous utilisons CloudFlare.

Détails: https://community.cloudflare.com/t/err-http2-protocol-error/119619 .

Section clé du post du forum:

Après des tests supplémentaires sur les onglets de navigation privée sur plusieurs navigateurs, puis après avoir effectué les modifications sur le code d'un BASE64 en une véritable image .png, le problème ne s'est plus jamais reproduit, dans N'IMPORTE QUEL navigateur. Le .png avait environ 500 Ko avant de devenir un base64, donc CloudFlare a des problèmes avec d'énormes lignes de texte sur la même ligne (car base64 est une longue chaîne) en tant que proxy entre le domaine et le heroku. Comme mentionné précédemment, le fait de frapper directement l'url Heroku n'est jamais arrivé.

Le hack temporaire consiste à désactiver HTTP / 2 sur CloudFlare.

J'espère que quelqu'un d'autre pourra produire une meilleure solution qui ne nécessite pas de désactiver HTTP / 2 sur CloudFlare.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.