¿De qué trata net :: ERR_HTTP2_PROTOCOL_ERROR?


36

Actualmente estoy trabajando en un sitio web, lo que provoca un net::ERR_HTTP2_PROTOCOL_ERROR 200error en Google Chrome. No estoy seguro exactamente qué puede provocar este error, solo noté que aparece solo cuando accedo al sitio web en HTTPS. No puedo estar 100% seguro de que esté relacionado, pero parece que impide que JavaScript se ejecute correctamente.

Por ejemplo, ocurre el siguiente escenario:

  1. Estoy accediendo al sitio web en HTTPS

  2. Mi feed de Twitter integrado a través de https://publish.twitter.com no está cargado en absoluto

  3. Puedo notar en la consola el ERR_HTTP2_PROTOCOL_ERROR

  4. Si elimino el código para cargar el feed de Twitter, el error permanece

  5. Si accedo al sitio web en HTTP, aparece el feed de Twitter y desaparece el error

Google Chrome es el único navegador web que activa el error: funciona bien tanto en Edge como en Firefox. (Nota: lo intenté con Safari y tengo un kcferrordomaincfnetwork 303error similar )

Me preguntaba si podría estar relacionado con el encabezado devuelto por el servidor ya que hay esta mención '200' en el error, y una página 404/500 no está activando nada.

La cosa es que el error no está documentado en absoluto. La búsqueda de Google me da muy pocos resultados. Además, noté que aparece en versiones muy recientes de Google Chrome; el error no aparece en v.64.X, pero sí en v.75 + (independientemente del sistema operativo; estoy trabajando en Mac).

¡Cualquier pista en este punto para investigar sería gratamente apreciada!

Gracias por adelantado.

Tristan


Edición 1: Puede estar relacionado con el sitio web OK en Firefox pero no en Safari (kCFErrorDomainCFNetwork error 303) ni Chrome (net :: ERR_SPDY_PROTOCOL_ERROR)


Edición 2: Los resultados de futuras investigaciones son los siguientes:

  • el error no aparece exactamente en la misma página si el servidor devuelve 404 en lugar de 2XX
  • el error no aparece en local con un certificado HTTPS
  • aparece un error en un servidor diferente (ambos son OVH), que usa un certificado diferente
  • aparece el error sin importar qué versión de PHP se use, de 5.6 a 7.3 (marco utilizado: Cakephp 2.10)

Edición 3: según lo solicitado, a continuación se muestra el encabezado devuelto para el recurso que falla, que es la página web completa. Incluso si el error se activa en cada página que tiene un encabezado HTTP 200, esas páginas siempre se están cargando en el navegador del cliente, pero a veces falta un elemento (en mi ejemplo, el feed externo de Twitter). Todos los demás activos en la pestaña Red tienen un retorno exitoso, excepto el documento completo en sí. línea que falló en la consola

Encabezado de Google Chrome (con error):

Encabezado de Chrome

Encabezado de Firefox (sin error):

Encabezado de Firefox

Una curl --head --http2solicitud en la consola devuelve el siguiente éxito:

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

Edición 4: Intentar profundizar con las herramientas chrome: // net-export / y https://netlog-viewer.appspot.com me dice que la solicitud termina con un RST_STREAM:

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

Por lo que leí en esta otra publicación , " En HTTP / 2, si el cliente desea cancelar la solicitud, envía un RST_STREAM. Cuando el servidor recibe un RST_STREAM, dejará de enviar tramas DATA al cliente, deteniendo así la respuesta (o la descarga). La conexión todavía se puede utilizar para otras solicitudes, y las solicitudes / respuestas que coincidieron con la que se ha cancelado pueden continuar progresando. [...] Es posible que para cuando RST_STREAM viaje desde el cliente al servidor, todo el contenido de la solicitud está en tránsito y llegará al cliente, que lo descartará. Sin embargo, para grandes contenidos de respuesta, el envío de un RST_STREAM puede tener una buena oportunidad de llegar al servidor antes de todo se envía contenido de respuesta y, por lo tanto, ahorrará ancho de banda " .

El comportamiento descrito es el mismo que puedo observar. Pero eso significaría que el navegador es el culpable, y entonces no entendería por qué sucede en dos páginas idénticas, una con un encabezado 200 y la otra un 404 (lo mismo ocurre si desactivo JS).



Obviamente he estado aquí, y solo hay respuestas relacionadas con el lado del cliente, que no pueden ser una solución.
Tristan G

¿Se produce el error en navegadores que no son de Chrome? si no, ¿cómo no es un problema del lado del cliente (específicamente el navegador Chrum)?
Jaromanda X

1
Probablemente un encabezado de respuesta HTTP con formato incorrecto. ¿No se está cargando todo el sitio? ¿O solo uno o más activos? ¿Puede editar la pregunta para incluir los encabezados de respuesta HTTP que se muestran en la respuesta http para un activo que no se carga al usar HTTP / 2? ¿Y también para Edge / Firefox donde funciona?
Barry Pollard

1
No puedo ver nada malo, así que sospecha que no es la solicitud principal. Ignora también las cookies, no es eso. Pruebe esto para ver si puede resolverlo: michalspacek.com/…
Barry Pollard

Respuestas:


7

Durante varias semanas también me molestó este "error":

net :: ERR_HTTP2_PROTOCOL_ERROR 200

En mi caso, ocurrió en imágenes generadas por PHP.

Estaba a header()nivel, y en este en particular:

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

Obviamente no devolvió el tamaño exacto, así que lo eliminé y todo funciona bien ahora.

Entonces Chrome verifica la precisión de los datos transmitidos a través de los encabezados, y si no corresponde, falla.

EDITAR

Descubrí por qué se estaba calculando erróneamente content-lengthvia filesize: la GZIPcompresión está activa en los archivos PHP, por lo que excluir el archivo en cuestión solucionará el problema. Pon este código en .htaccess:

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

Funciona y mantenemos el encabezado Content-length.


1
Genial, me salvaste !!! Pero todavía no entiendo el problema real, en mi caso el error solo ocurre en https pero no en http.
Nico

Hola @Nico, sí, creo que es normal, la verificación entre el tamaño anunciado y el del archivo descargado por el navegador (Chrome) solo debe hacerse en el protocolo https. ¡Muy feliz de que esta solución pueda ayudarlo!
Xtendo

1
De alguna manera logré usar "Content -Length" en lugar de "Content-Length". Después de quitar el espacio, funcionó. Gracias.
Martin Lottering

Hola @Martin Lottering ¡Me alegra que te funcione ahora! :-)
Xtendo

6

No descubrí qué estaba sucediendo exactamente, pero encontré una solución.

La característica CDN de OVH fue la culpable. Lo instalé en mi servicio de host pero lo deshabilité para mi dominio porque no lo necesitaba.

De alguna manera, cuando lo habilito, todo funciona.

Creo que obliga a Apache a usar el protocolo HTTP2, pero lo que no entiendo es que efectivamente hubo una mención de HTTP2 en cada uno de mis encabezados, lo que supongo que significa que el servidor estaba respondiendo usando el protocolo correcto.

Entonces, la solución para mi caso muy particular fue habilitar la opción CDN en todos los dominios involucrados.

Si alguien comprende mejor lo que podría haber sucedido aquí, no dude en compartir explicaciones.


purgar el caché de
CDN

4

Encontré esto porque el servidor http2 cerró la conexión al enviar una gran respuesta al Chrome.

¿Por qué? Porque es solo una configuración del servidor http2, llamada WriteTimeout .


4

En mi caso, fue: no queda espacio en disco en el servidor web.


Interesante, para mí lo mismo, el servidor web frontal tenía el disco lleno. Parece que nginx no detecta esta situación porque no había nada notable en el registro.
vchrizz

3

Experimenté un problema similar, estaba obteniendo ERR_HTTP2_PROTOCOL_ERROR en una de las solicitudes HTTP GET.

Noté que la actualización de Chrome estaba pendiente, así que actualicé el navegador Chrome a la última versión y el error desapareció la próxima vez que reinicié el navegador.


2

Tuve este problema cuando tenía un servidor Nginx que exponía la aplicación node-js al mundo externo. El Nginx comprimió el archivo (css, js, ...) gzipy con Chrome se veía igual.

El problema se resolvió cuando descubrimos que el servidor node-js también está comprimido en el contenido con gzip. De alguna manera, esta doble compresión conduce a este problema. La cancelación de la compresión node-js resolvió el problema.


66
Es interesante ver que varias personas ya han respondido esta publicación, y cada vez que la raíz del problema era algo diferente. Creo que este error es bastante confuso.
Tristan G

2

Este error se está solucionando actualmente: https://chromium-review.googlesource.com/c/chromium/src/+/2001234

Pero me ayudó, cambiando la configuración de nginx:

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

En mi caso, Nginx actúa como un proxy inverso para la aplicación Node.js.


Esta respuesta también funcionó para mí. Siga este enlace docs.nginx.com/nginx/admin-guide/web-server/compression para una sintaxis adecuada
Bhargavi Gopalachar

1

Esto me sucedió cuando registré un nuevo nombre de dominio, por ejemplo, "nuevo" por ejemplo.com (nuevo.ejemplo.com). El nombre no se pudo resolver temporalmente en mi ubicación durante un par de horas, mientras que se pudo resolver en el extranjero. Así que utilicé un proxy para probar el sitio web donde vi net::ERR_HTTP2_PROTOCOL_ERRORen la consola de Chrome algunas publicaciones de AJAX. Horas después, cuando el nombre podía ser reslocado localmente, esos errores simplemente desaparecieron.

Creo que la razón de ese error es que esas solicitudes AJAX no fueron redirigidas por mi proxy, solo visitan un sitio web que no ha sido resuelto por mi resolución DNS local.


1

Enfrenté este error varias veces y se debió a la transferencia de grandes recursos (más de 3 MB) del servidor al cliente.


0

Tuve el mismo problema (asp, c # - HttpPostedFileBase) al publicar un archivo que era mayor de 1 MB (aunque la aplicación no tiene ninguna limitación para el tamaño del archivo), para mí la simplificación de la clase de modelo ayudó. Si tiene este problema, intente eliminar algunas partes del modelo y vea si ayudará de alguna manera. Suena extraño, pero funcionó para mí.


0

He estado experimentando este problema durante la última semana, ya que he estado tratando de enviar solicitudes DELETE a mi servidor PHP a través de AJAX. Recientemente actualicé mi plan de alojamiento donde ahora tengo un Certificado SSL en mi host que almacena los archivos PHP y JS. Desde que agregué un Certificado SSL ya no tengo este problema. Esperando que esto ayude con este extraño error.


0

También me enfrenté a este error y creo que puede haber múltiples razones detrás de él. La mía era, ARR se estaba agotando.

En mi caso, el navegador estaba haciendo una solicitud a un sitio proxy inverso donde he establecido mis reglas de redirección y ese sitio proxy eventualmente solicita el sitio real. Ahora, para obtener grandes datos, tomaba más de 2 minutos y 5 segundos y el tiempo de espera de enrutamiento de solicitud de aplicación para mi servidor se estableció en 2 minutos. Lo arreglé aumentando el tiempo de espera de ARR siguiendo los pasos a continuación: 1. Vaya a IIS 2. Haga clic en el nombre del servidor 3. Haga clic en Caché de enrutamiento de solicitud de aplicación en el panel central 4. Haga clic en Configuración del servidor proxy en el panel derecho 5. Aumente el tiempo de espera 6 Haga clic en Aplicar


0

En nuestro caso, el motivo era un encabezado no válido. Como se menciona en la Edición 4:

  • toma los troncos
  • en el visor, seleccione Eventos
  • eligió HTTP2_SESSION

Busca algo similar:

HTTP2_SESSION_RECV_INVALID_HEADER

-> error = "Carácter no válido en el nombre del encabezado".

-> header_name = " charset = utf-8 "


0

Mi equipo vio esto en un solo archivo javascript que estábamos sirviendo. Todos los demás archivos funcionaron bien. Cambiamos de http2atrás a http1.1y luego net::ERR_INCOMPLETE_CHUNKED_ENCODINGo bien ERR_CONTENT_LENGTH_MISMATCH. Finalmente descubrimos que había un filtro corporativo (Trustwave) que detectaba erróneamente una "fuga de información" (sospechamos que detectó algo en nuestro archivo / nombre de archivo que se parecía a un número de seguro social). Ponernos corporativos para ajustar este filtro resolvió nuestros problemas.


0

Experimentamos este problema en páginas con cadenas Base64 largas. El problema ocurre porque usamos CloudFlare.

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

Sección clave de la publicación del foro:

Después de realizar más pruebas en las pestañas de incógnito en varios navegadores, luego de hacer los cambios en el código de BASE64 a una imagen .png real, el problema nunca volvió a ocurrir, en CUALQUIER navegador. El .png tenía alrededor de 500 kb antes de convertirse en una base64, por lo que CloudFlare tiene problemas con grandes líneas de texto en la misma línea (ya que base64 es una cadena larga) como proxy entre el dominio y el heroku. Como se mencionó anteriormente, golpear directamente la URL de Heroku tampoco sucedió.

El truco temporal es deshabilitar HTTP / 2 en CloudFlare.

Espero que alguien más pueda producir una mejor solución que no requiera deshabilitar HTTP / 2 en CloudFlare.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.