Di cosa tratta la rete :: ERR_HTTP2_PROTOCOL_ERROR?


36

Attualmente sto lavorando su un sito Web, che genera un net::ERR_HTTP2_PROTOCOL_ERROR 200errore su Google Chrome. Non sono sicuro di cosa possa provocare questo errore, ho appena notato che viene visualizzato solo quando si accede al sito Web in HTTPS. Non posso essere sicuro al 100% che sia correlato, ma sembra che impedisca l'esecuzione corretta di JavaScript.

Ad esempio, si verifica il seguente scenario:

  1. Sto accedendo al sito Web in HTTPS

  2. Il mio feed Twitter integrato tramite https://publish.twitter.com non è caricato affatto

  3. Posso notare nella console ERR_HTTP2_PROTOCOL_ERROR

  4. Se rimuovo il codice per caricare il feed di Twitter, l'errore rimane

  5. Se accedo al sito Web in HTTP, viene visualizzato il feed Twitter e l'errore scompare

Google Chrome è l'unico browser Web che attiva l'errore: funziona bene su Edge e Firefox. (NB: ho provato con Safari e ho un kcferrordomaincfnetwork 303errore simile )

Mi chiedevo se potesse essere correlato all'intestazione restituita dal server poiché c'è questa menzione "200" nell'errore e una pagina 404/500 non sta attivando nulla.

La cosa è che l'errore non è affatto documentato. La ricerca di Google mi dà pochissimi risultati. Inoltre, ho notato che appare su versioni molto recenti di Google Chrome; l'errore non viene visualizzato su v.64.X, ma su v.75 + (indipendentemente dal sistema operativo; sto lavorando su Mac tho).

Qualsiasi indizio a questo punto per indagare sarebbe felicemente apprezzato!

Grazie in anticipo.

Tristan


Modifica 1: potrebbe essere correlato al sito Web OK su Firefox ma non su Safari (errore 303 kCFErrorDomainCFNetwork) né Chrome (net :: ERR_SPDY_PROTOCOL_ERROR)


Modifica 2: i risultati di ulteriori indagini sono i seguenti:

  • l'errore non viene visualizzato esattamente sulla stessa pagina se il server restituisce 404 anziché 2XX
  • l'errore non viene visualizzato in locale con un certificato HTTPS
  • viene visualizzato un errore su un server diverso (entrambi sono OVH), che utilizza un certificato diverso
  • l'errore viene visualizzato indipendentemente dalla versione di PHP, dalla 5.6 alla 7.3 (framework utilizzato: Cakephp 2.10)

Modifica 3: come richiesto, di seguito è riportata l'intestazione restituita per la risorsa non riuscita, che è l'intera pagina Web. Anche se l'errore si sta verificando su ogni pagina con un'intestazione HTTP 200, quelle pagine vengono sempre caricate sul browser del client, ma a volte manca un elemento (nel mio esempio, il feed Twitter esterno). Ogni altra risorsa nella scheda Rete ha un ritorno positivo, tranne l'intero documento stesso. linea non riuscita nella console

Intestazione di Google Chrome (con errore):

Intestazione di Chrome

Intestazione di Firefox (senza errori):

Intestazione di Firefox

Una curl --head --http2richiesta in console restituisce il seguente successo:

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

Modifica 4: Cercare di approfondire gli strumenti chrome: // net-export / e https://netlog-viewer.appspot.com mi sta dicendo che la richiesta termina con un RST_STREAM:

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

Per quello che ho letto in questo altro post , " In HTTP / 2, se il client desidera interrompere la richiesta, invia un RST_STREAM. Quando il server riceve un RST_STREAM, interromperà l'invio di frame DATI al client, interrompendo così la risposta (o il download). La connessione è ancora utilizzabile per altre richieste e le richieste / risposte che erano simultanee a quella che è stata interrotta possono continuare a progredire. [...] È possibile che, quando RST_STREAM viaggia da dal client al server, l'intero contenuto della richiesta è in transito e arriverà al client, che lo scarterà. Tuttavia, per contenuti di risposta di grandi dimensioni, l'invio di un RST_STREAM può avere buone probabilità di arrivare al server prima dell'intero il contenuto della risposta viene inviato e pertanto consente di risparmiare larghezza di banda " .

Il comportamento descritto è lo stesso di quello che posso osservare. Ciò significherebbe che il colpevole è il browser, e quindi non capirei perché accade su due pagine identiche con una con intestazione 200 e l'altra con 404 (lo stesso vale se disabilito JS).



Sono stato qui ovviamente e ci sono solo risposte relative al lato client, che non possono essere una soluzione.
Tristan G,

si verifica l'errore nei browser non Chrome? in caso contrario, in che modo non è un problema lato client (in particolare il browser Chrum)?
Jaromanda X,

1
Probabili intestazioni di risposta HTTP non valide. L'intero sito non si sta caricando? O solo una o più risorse? È possibile modificare la domanda per includere le intestazioni di risposta HTTP mostrate nella risposta http per un asset che non si carica quando si utilizza HTTP / 2? E anche per Edge / Firefox dove funziona?
Barry Pollard,

1
Non riesco a vedere nulla di sbagliato lì, quindi sospetto che non sia la richiesta principale. Ignora anche la cosa dei cookie - non è quello. Prova questo per vedere se riesci a capire: michalspacek.com/…
Barry Pollard

Risposte:


7

Per diverse settimane sono stato anche infastidito da questo "bug":

net :: ERR_HTTP2_PROTOCOL_ERROR 200

Nel mio caso, si è verificato su immagini generate da PHP.

Era a header()livello, e su questo in particolare:

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

Ovviamente non ha restituito la dimensione esatta, quindi l'ho eliminato e ora funziona tutto bene.

Quindi Chrome verifica l'accuratezza dei dati trasmessi tramite le intestazioni e, se non corrisponde, non riesce.

MODIFICARE

Ho scoperto perché content-lengthvia filesizeveniva calcolato male: la GZIPcompressione è attiva sui file PHP, quindi l'esclusione del file in questione risolverà il problema. Inserisci questo codice in .htaccess:

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

Funziona e manteniamo l'intestazione Content-length.


1
Fantastico mi hai salvato !!! Ma ancora non capisco il vero problema, nel mio caso l'errore si verifica solo in https ma non in http.
Nico,

Ciao @Nico, sì, penso sia normale, la verifica tra la dimensione annunciata e quella del file scaricato dal browser (Chrome) dovrebbe essere effettuata solo nel protocollo https. Molto felice che questa soluzione possa aiutarti!
Xtendo,

1
In qualche modo sono riuscito a usare "Content -Length" invece di "Content-Length". Dopo aver rimosso lo spazio, ha funzionato. Grazie.
Martin Lottering,

Ciao @Martin Lottering Molto felice che funzioni per te adesso! :-)
Xtendo

6

Non ho capito cosa stesse succedendo esattamente, ma ho trovato una soluzione.

La caratteristica CDN di OVH era il colpevole. L'avevo installato sul mio servizio host ma disabilitato per il mio dominio perché non ne avevo bisogno.

In qualche modo, quando lo abilito, tutto funziona.

Penso che costringa Apache a usare il protocollo HTTP2, ma ciò che non capisco è che in ognuna delle mie intestazioni c'era effettivamente una menzione HTTP2, che presumo significhi che il server stava rispondendo usando il protocollo giusto.

Quindi la soluzione per il mio caso molto particolare era abilitare l'opzione CDN su tutti i domini interessati.

Se qualcuno capisce meglio cosa potrebbe essere successo qui, sentiti libero di condividere spiegazioni.


spurgo cache cdn ha funzionato per me
Varshaan il

4

Ho riscontrato questo perché il server http2 ha chiuso la connessione durante l'invio di una grande risposta a Chrome.

Perché? Perché è solo un'impostazione del server http2, denominata WriteTimeout .


4

Nel mio caso lo era - nessuno spazio su disco è rimasto sul server web.


interessante, per me lo stesso, il server web anteriore aveva il disco pieno. sembra che nginx non rilevi questa situazione perché non c'era nulla di evidente nel registro.
vchrizz,

3

Ho riscontrato un problema simile, stavo ricevendo ERR_HTTP2_PROTOCOL_ERROR su una delle richieste HTTP GET.

Ho notato che l'aggiornamento di Chrome era in sospeso, quindi ho aggiornato il browser Chrome all'ultima versione e l'errore è scomparso la prossima volta quando ho riavviato il browser.


2

Ho avuto questo problema quando avevo un server Nginx che esponeva l'applicazione node-js al mondo esterno. Nginx ha reso il file (css, js, ...) compresso con gzipe con Chrome sembrava lo stesso.

Il problema è stato risolto quando abbiamo scoperto che anche il server node-js comprime il contenuto con gzip. In qualche modo, questa doppia compressione porta a questo problema. L'annullamento della compressione di node-js ha risolto il problema.


6
È interessante vedere che diverse persone hanno già risposto a questo post e ogni volta la radice del problema era qualcosa di diverso. Penso che questo errore sia piuttosto confuso.
Tristan G,

2

Questo errore è attualmente in fase di correzione: https://chromium-review.googlesource.com/c/chromium/src/+/2001234

Ma mi ha aiutato, cambiando le impostazioni di nginx:

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

Nel mio caso, Nginx funge da proxy inverso per l'applicazione Node.js.


questa risposta ha funzionato anche per me. Segui questo link docs.nginx.com/nginx/admin-guide/web-server/compression per la sintassi corretta
Bhargavi Gopalachar

1

Questo mi è successo quando ho registrato un nuovo nome di dominio, ad esempio "nuovo" per esempio.com (nuovo.esempio.com). Il nome non può essere risolto temporaneamente nella mia posizione per un paio d'ore, mentre potrebbe essere risolto all'estero. Quindi ho usato un proxy per testare il sito Web in cui ho visto net::ERR_HTTP2_PROTOCOL_ERRORnella console Chrome per alcuni post AJAX. Ore dopo, quando il nome poteva essere resloved localmente, quell'errore era semplicemente scomparso.

Penso che la ragione di quell'errore sia che le richieste AJAX non sono state reindirizzate dal mio proxy, ma solo visitare un sito Web che non era stato risolto dal mio resolver DNS locale.


1

Ho riscontrato questo errore diverse volte ed era dovuto al trasferimento di risorse di grandi dimensioni (superiori a 3 MB) dal server al client.


0

Ho avuto lo stesso problema (asp, c # - HttpPostedFileBase) durante la pubblicazione di un file che era più grande di 1 MB (anche se l'applicazione non ha alcuna limitazione per le dimensioni del file), per me la semplificazione della classe del modello ha aiutato. Se hai riscontrato questo problema, prova a rimuovere alcune parti del modello e vedi se ti aiuterà in qualche modo. Sembra strano, ma ha funzionato per me.


0

Ho riscontrato questo problema nell'ultima settimana mentre provavo a inviare richieste DELETE al mio server PHP tramite AJAX. Di recente ho aggiornato il mio piano di hosting dove ora ho un certificato SSL sul mio host che memorizza i file PHP e JS. Da quando ho aggiunto un certificato SSL non ho più riscontrato questo problema. Sperando che questo aiuti con questo strano errore.


0

Ho anche riscontrato questo errore e credo che ci possano essere diverse ragioni dietro. Il mio era, l'ARR stava scadendo.

Nel mio caso, il browser stava facendo una richiesta a un sito proxy inverso in cui ho impostato le mie regole di reindirizzamento e quel sito proxy alla fine richiede il sito reale. Ora per dati enormi ci sono voluti più di 2 minuti e 5 secondi e il timeout del routing delle richieste dell'applicazione per il mio server è stato impostato su 2 minuti. Ho risolto questo problema aumentando il timeout ARR con i passaggi seguenti: 1. Vai a IIS 2. Fai clic sul nome del server 3. Fai clic su Cache di routing richiesta applicazione nel riquadro centrale 4. Fai clic su Impostazioni proxy server nel riquadro destro 5. Aumenta il timeout 6 Fai clic su Applica


0

Nel nostro caso, il motivo era un'intestazione non valida. Come menzionato in Modifica 4:

  • prendi i registri
  • nel visualizzatore selezionare Eventi
  • ha scelto HTTP2_SESSION

Cerca qualcosa di simile:

HTTP2_SESSION_RECV_INVALID_HEADER

-> errore = "Carattere non valido nel nome dell'intestazione."

-> header_name = " charset = utf-8 "


0

Il mio team lo ha visto su un singolo file javascript che stavamo offrendo. Ogni altro file ha funzionato bene. Siamo passati da http2indietro a http1.1e poi o net::ERR_INCOMPLETE_CHUNKED_ENCODINGo ERR_CONTENT_LENGTH_MISMATCH. Alla fine abbiamo scoperto che c'era un filtro aziendale (Trustwave) che stava erroneamente rilevando un "infoleak" (sospettiamo che abbia rilevato qualcosa nel nostro file / nome file che somigliasse a un numero di previdenza sociale). Ottenere che l'azienda modifichi questo filtro ha risolto i nostri problemi.


0

Abbiamo riscontrato questo problema su pagine con stringhe Base64 lunghe. Il problema si verifica perché utilizziamo CloudFlare.

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

Sezione chiave dal post del forum:

Dopo ulteriori test sulle schede di navigazione in incognito su più browser, quindi apportando le modifiche al codice da un BASE64 a un'immagine reale .png, il problema non si è mai più verificato, in QUALSIASI browser. Il .png aveva circa 500kb prima di diventare base64, quindi CloudFlare ha problemi con enormi righe di testo sulla stessa riga (poiché base64 è una stringa lunga) come proxy tra il dominio e l'heroku. Come accennato in precedenza, anche colpire direttamente l'url di Heroku non si è mai verificato il problema.

L'hack temporaneo è disabilitare HTTP / 2 su CloudFlare.

Spero che qualcun altro possa produrre una soluzione migliore che non richiede la disabilitazione di HTTP / 2 su CloudFlare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.