ERR_HTTP2_PROTOCOL_ERROR : signification et solutions
Point clé
ERR_HTTP2_PROTOCOL_ERROR (erreur Chromium -337) signifie que le flux HTTP/2 qui transporte la page a échoué. Soit le serveur, le proxy ou le CDN l'a réinitialisé en cours de route (Chrome signale toute réinitialisation de ce genre par -337), soit Chrome a rejeté des en-têtes qui enfreignent les règles de HTTP/2. En tant que visiteur, un rechargement, une fenêtre de navigation privée, l'effacement des cookies du site ou la mise en pause de l'analyse HTTPS de l'antivirus permettent parfois de passer, mais en général seul le site peut corriger le problème. Côté propriétaire de site, les causes habituelles sont une réponse que le serveur ou le proxy n'a pas pu terminer (disque plein, dossier temporaire non inscriptible, application qui plante), un Content-Length qui ne correspond pas au corps, ou un en-tête interdit comme Transfer-Encoding. Reproduisez l'erreur avec curl --http2 -v.
Vérifiez maintenant

Commencer la lecture
- Qu'est-ce que ERR_
HTTP2_ PROTOCOL_ ERROR ? - Ce que HTTP/2 considère comme mal formé
- Quelles sont les causes de ERR_
HTTP2_ PROTOCOL_ ERROR ? - Solution 1 : rechargement forcé et navigation privée
- Solution 2 : effacez les cookies et les fichiers en cache de ce site
- Solution 3 : suspendez l'analyse HTTPS de l'antivirus et les extensions
- Solution 4 : mettez Chrome à jour et testez d'autres navigateurs
- Solution 5 : testez la page sans HTTP/2
- Pour les propriétaires de sites : corriger les erreurs de protocole HTTP/2
- 1. Reproduisez l'erreur avec curl
- 2. Cherchez les réponses coupées en plein flux
- 3. Corrigez le Content-Length et les en-têtes interdits
- ERR_
HTTP2_ PROTOCOL_ ERROR et les erreurs similaires - Questions fréquemment posées
Qu'est-ce que ERR_HTTP2_PROTOCOL_ERROR ?
ERR_HTTP2_PROTOCOL_ERROR est une erreur de Chrome et d'Edge qui signifie que le flux HTTP/2 qui transporte la page a échoué : le serveur l'a réinitialisé avant la fin ou a envoyé des en-têtes que le navigateur rejette. Dans Chromium, il s'agit de l'erreur réseau -337 : « There is an HTTP/2 protocol error » (net_error_list.h). Chrome n'a pas de page d'erreur dédiée, vous voyez donc la page générique : « Ce site est inaccessible. La page Web à l'adresse … est peut-être temporairement inaccessible ou a peut-être été déplacée de façon permanente vers une nouvelle adresse Web », avec ERR_HTTP2_PROTOCOL_ERROR en dessous. Edge affiche le même code sur sa propre page d'erreur.
HTTP/2 est la version plus rapide de HTTP que la plupart des sites HTTPS utilisent aujourd'hui. Chaque requête circule dans son propre flux au sein d'une seule connexion, et chaque côté peut annuler un flux par une réinitialisation. Chrome signale toute réinitialisation venue du serveur comme une erreur de protocole, quelle que soit la raison du serveur. Il annule aussi lui-même un flux lorsque les en-têtes enfreignent les règles de HTTP/2 (un en-tête Transfer-Encoding, des majuscules dans un nom d'en-tête, un statut manquant).
Les développeurs la voient souvent dans la console des DevTools sous la forme net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK). Cette combinaison est un indice fort : les en-têtes étaient valides et le serveur a répondu 200, mais le flux a échoué pendant l'arrivée du corps.
Voyez les en-têtes qu'une page envoie réellement
Ce que HTTP/2 considère comme mal formé
La norme HTTP/2 (RFC 9113) énumère les erreurs qui rendent une réponse invalide. Ce sont les problèmes derrière la plupart des erreurs réelles, et voici comment chacun atteint le navigateur :
| Règle | Ce qui l'enfreint |
|---|---|
| Content-Length doit être égal à la taille du corps | Un serveur ou un plugin annonce une taille et en envoie une autre ; le proxy, le CDN ou le serveur placé devant réinitialise alors le flux |
| La réponse doit se terminer proprement | Le serveur, le proxy ou l'application ne peut pas la terminer (disque plein, plantage, délai dépassé) et réinitialise le flux ; nginx le fait quand il ne peut pas achever une réponse déjà commencée |
| Pas d'en-têtes propres à la connexion | Transfer-Encoding dans une réponse HTTP/2 (Chrome la rejette) ; Connection, Keep-Alive, Proxy-Connection et Upgrade sont aussi interdits, et des clients stricts comme curl les rejettent |
| Les noms de champs doivent être en minuscules | Des noms d'en-têtes avec des majuscules transmis tels quels à HTTP/2 |
| Valeurs d'en-tête valides | Des sauts de ligne ou d'autres caractères interdits dans une valeur d'en-tête |
| Un pseudo-en-tête :status valide | Un code de statut manquant ou illisible |
Quelles sont les causes de ERR_HTTP2_PROTOCOL_ERROR ?
La plupart des cas viennent du serveur, mais quelques éléments de votre propre ordinateur peuvent abîmer une réponse à son arrivée :
- Côté serveur : une réponse que le serveur ou le proxy ne peut pas terminer (un proxy à court d'espace disque ou qui ne peut pas écrire ses fichiers temporaires, une application qui plante pendant le streaming, un délai dépassé), de mauvaises valeurs de Content-Length qui font abandonner le proxy placé devant, des en-têtes interdits ou invalides, et une prise en charge de HTTP/2 défaillante dans un ancien serveur ou une ancienne configuration de CDN.
- De votre côté : un antivirus ou un pare-feu qui inspecte le HTTPS et réécrit le trafic, des extensions de navigateur qui modifient les requêtes ou les réponses, une requête que le serveur traite mal (par exemple des cookies trop volumineux) et, parfois, une version de Chrome obsolète.
Solution 1 : rechargement forcé et navigation privée
Appuyez sur Ctrl + Maj + R (Mac : Cmd + Maj + R) pour recharger sans le cache. Une réponse coupée une fois peut très bien passer à la tentative suivante.
Ouvrez ensuite la page dans une fenêtre de navigation privée (Ctrl + Maj + N, sur Mac Cmd + Maj + N). La navigation privée n'a ni cookies ni cache de votre profil habituel, et les extensions y sont désactivées par défaut. Si la page s'y charge, la solution 2 ou la solution 3 réglera le problème dans votre fenêtre normale.
Solution 2 : effacez les cookies et les fichiers en cache de ce site
Effacer les cookies et les fichiers en cache du site modifie la requête que Chrome envoie (moins de cookies, pas de copie en cache à revalider), ce qui peut contourner un bogue du serveur. Cliquez sur Afficher des informations à propos du site à gauche de la barre d'adresse → Cookies et données des sites → Gérer les données des sites sur l'appareil → supprimez, puis rechargez. Pour un nettoyage plus large, appuyez sur Ctrl + Maj + Suppr et effacez les Images et fichiers en cache pour les 7 derniers jours.
Solution 3 : suspendez l'analyse HTTPS de l'antivirus et les extensions
Un logiciel de sécurité qui déchiffre et inspecte le HTTPS se place au milieu de chaque connexion HTTP/2. Si sa gestion de HTTP/2 est boguée ou obsolète, il peut casser des flux ou transmettre des en-têtes que Chrome rejette. Désactivez uniquement la fonction d'analyse HTTPS (Avast/AVG : Agent Web → Enable HTTPS scanning ; ESET : Filtrage du protocole SSL/TLS ; Kaspersky : Analyser les connexions chiffrées) et rechargez. Si cela règle le problème, mettez l'antivirus à jour et ajoutez une exclusion pour le site.
Ensuite, désactivez toutes les extensions sur chrome://extensions, rechargez, puis réactivez-les une par une. Les bloqueurs de publicités, les outils de confidentialité et tout ce qui modifie les en-têtes sont les suspects habituels.
Solution 4 : mettez Chrome à jour et testez d'autres navigateurs
Ouvrez chrome://settings/help pour installer une éventuelle mise à jour, puis redémarrez le navigateur. Ouvrez ensuite la même page dans Firefox ou Safari, ainsi que sur un autre appareil ou un autre réseau. Si elle échoue partout, le site est cassé et seul son propriétaire peut le corriger (l'analyse HTTPS d'un antivirus touche tous les navigateurs d'un même ordinateur : un second appareil est donc le vrai test). Si seuls Chrome ou Edge échouent, le site envoie probablement un en-tête que Chrome rejette ; les solutions 2 et 3 valent quand même un nouvel essai.
Solution 5 : testez la page sans HTTP/2
Chrome peut être lancé avec HTTP/2 (et HTTP/3) désactivés, ce qui montre si HTTP/2 est en cause. Lancez depuis un terminal un second Chrome, séparé ; le dossier de profil supplémentaire en fait une nouvelle instance même si votre Chrome habituel est ouvert :
# Windows (Command Prompt)
"C:\Program Files\Google\Chrome\Application\chrome.exe" --user-data-dir="%TEMP%\h2test" --disable-http2 --disable-quic
# macOS (Terminal)
open -na "Google Chrome" --args --user-data-dir=/tmp/h2test --disable-http2 --disable-quicSi la page se charge dans cette fenêtre, ses réponses HTTP/2 sont le problème et le propriétaire doit les corriger. Si elle échoue maintenant avec ERR_CONTENT_LENGTH_MISMATCH ou ERR_INCOMPLETE_CHUNKED_ENCODING, le serveur coupe la réponse quel que soit le protocole. Fermez cette fenêtre quand vous avez fini ; votre Chrome habituel n'est pas touché.
Pour les propriétaires de sites : corriger les erreurs de protocole HTTP/2
Si des visiteurs sur des réseaux et des navigateurs différents signalent l'erreur, le problème se trouve dans votre infrastructure. Ces trois vérifications les trouvent presque toutes.
1. Reproduisez l'erreur avec curl
# HTTP/2: watch the end of the output
curl -sv --http2 https://example.com/broken-page -o /dev/null
# A stream the server gave up on ends with something like:
# HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)
# (curl 8.19+: HTTP/2 stream 1 reset by server (error 0x2 INTERNAL_ERROR);
# "reset by curl" means curl rejected the response itself)
# Same URL over HTTP/1.1 for comparison
curl -sv --http1.1 https://example.com/broken-page -o /dev/nullSi HTTP/1.1 fonctionne et que HTTP/2 échoue, HTTP/2 est en cause. « Reset by server » indique que le serveur ou un proxy a abandonné en cours de réponse. curl ne vérifie pas exactement ce que vérifie Chrome (il rejette les écarts de Content-Length et les en-têtes de connexion que Chrome laisse passer) : considérez-le comme un indice fort, pas comme une preuve. Le vérificateur d'en-têtes HTTP liste les en-têtes que votre application définit, vus depuis l'extérieur de votre réseau.
2. Cherchez les réponses coupées en plein flux
La cause la plus fréquente côté serveur est une réponse qui démarre (statut 200, en-têtes envoyés) puis ne peut pas être terminée. nginx met en mémoire tampon les réponses plus volumineuses de votre application dans des fichiers temporaires ; si le disque est plein ou si nginx ne peut pas écrire dans son dossier temporaire, il réinitialise le flux et le navigateur signale une erreur de protocole. Vérifiez :
df -h # is any disk full?
sudo grep -E "No space left|Permission denied" /var/log/nginx/error.log | tail
ls -ld /var/lib/nginx/proxy /var/lib/nginx/fastcgi # Debian/Ubuntu packages
ls -ld /var/cache/nginx/proxy_temp /var/cache/nginx/fastcgi_temp # nginx.org packages
# the temp folders must be writable by the nginx worker userVérifiez aussi l'application elle-même : un processus PHP ou Node qui plante, dépasse un délai ou atteint une limite de mémoire pendant l'envoi d'une grosse page ou d'un téléchargement produit le même résultat. Les logs de l'application autour de l'heure de l'erreur le montrent généralement.
3. Corrigez le Content-Length et les en-têtes interdits
- Content-Length : laissez le serveur le calculer. Ne le définissez pas à la main dans le code de l'application si un plugin, un middleware ou le serveur web compresse ou modifie aussi la sortie, car la longueur annoncée ne correspond alors plus aux octets envoyés. Une longueur fixée dans le code PHP alors qu'un plugin ou un réglage PHP compresse aussi la sortie est une façon dont cela arrive sur les sites WordPress.
- Transfer-Encoding : ne l'envoyez jamais dans une réponse HTTP/2 ; Chrome réinitialise le flux dès qu'il en voit un. La RFC 9113 interdit aussi
Connection,Keep-Alive,Proxy-ConnectionetUpgrade. Chrome les ignore, mais curl et d'autres clients stricts les rejettent, et nginx retire la plupart d'entre eux des réponses proxifiées à votre place. - Valeurs d'en-tête : assurez-vous qu'aucun en-tête ne contient de saut de ligne ni de caractère de contrôle. Cela vient souvent d'une saisie utilisateur placée dans un en-tête, comme un nom de fichier dans
Content-Disposition. - CDN en amont : si vous utilisez Cloudflare ou un autre CDN, testez directement l'origine (avec curl
--resolveou une entrée hosts) pour savoir si l'erreur vient de l'origine ou du CDN.
ERR_HTTP2_PROTOCOL_ERROR et les erreurs similaires
| Erreur | Code | Ce qui s'est passé |
|---|---|---|
| ERR_HTTP2_PROTOCOL_ERROR | -337 | Une réponse HTTP/2 a enfreint les règles du protocole |
| ERR_QUIC_PROTOCOL_ERROR | -356 | Le même type d'échec en HTTP/3 (QUIC) |
| ERR_SSL_PROTOCOL_ERROR | -107 | La négociation HTTPS (TLS) a échoué avant le démarrage de HTTP/2 |
| ERR_CONNECTION_CLOSED | -100 | La connexion a été fermée avant l'arrivée d'une page |
| ERR_EMPTY_RESPONSE | -324 | Le serveur n'a rien envoyé du tout |
Guides détaillés : ERR_QUIC_PROTOCOL_ERROR, ERR_SSL_PROTOCOL_ERROR, ERR_CONNECTION_CLOSED et ERR_EMPTY_RESPONSE. Pour vérifier le certificat et la configuration HTTPS d'un site depuis l'extérieur, utilisez le Vérificateur SSL.
Voyez les en-têtes que votre site envoie réellement
Le vérificateur d'en-têtes HTTP de DNS Robot récupère n'importe quelle URL en HTTP/1.1 depuis nos serveurs et liste le code de statut et chaque en-tête de réponse que votre application définit (Content-Length, Content-Encoding, Content-Disposition), pour que vous puissiez les comparer à ce que montre curl --http2.


