Chrome net::ERR_HTTP2_PROTOCOL_ERROR 200 after a reconnect

fabrice picture fabrice · Apr 1, 2020 · Viewed 23k times · Source

I'm using Node server with an express app which handles a Server Sent Events stream. This is proxied via NginX with http2 enabled. The SSE events are consumed via EventSource in a React app. I'm sending a heartbeat message every 10 seconds to keep the connection alive.

This all works great until there is some form of network interruption such as putting my laptop to sleep then re-awaking it.

Then from that point on the stream will error every 40 or so seconds with the net::ERR_HTTP2_PROTOCOL_ERROR 200 error and then reconnect instead of just reconnecting once with a steady stream.

Firefox works correctly. It doesn't error and reconnects only once.

If I configure Node to serve http2 directly instead of via NGinx as a test (via spdy library) then all works as expected so I don't think this is a Node issue and I must be missing something with my Nginx configuration and Chrome.

Nginx config as follows (location /stream is the SSE proxy)

server {
    listen 28443 ssl http2;
    listen [::]:28443 ssl http2;

    server_name example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    http2_max_field_size 16k;
    http2_max_header_size 128k;

    root /var/www/example.com;
    index index.html index.htm;

    location / {
        client_max_body_size 100M;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_pass http://localhost:28080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'Upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location /stream {
        proxy_http_version 1.1;
        # proxy_request_buffering off;
        # proxy_buffering off;
        # proxy_cache off;
        # chunked_transfer_encoding off;
        proxy_set_header    Connection          '';
        proxy_set_header  Host            $host;
        proxy_set_header  X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:28080/stream;
    }
}

I've tried various combinations with proxy_buffers off and keepalive settings ect.. which seems to only affect the time between errors i.e. 5 minutes instead of 40 seconds.

Answer

Elevenfox picture Elevenfox · Sep 4, 2020

Not sure if you figure this out. I got the same issue recently, by increasing the size:

http2_max_field_size 64k;
http2_max_header_size 512k;

The chrome's net::ERR_HTTP2_PROTOCOL_ERROR has gone.

Also, not sure if it applied to you. If I use firefox, I can actually visit my site correctly.