Missing Sec-WebSocket-Key in WebSocket connection handshake

Viewed 646

Since yesterday we have had a problem with WebSocket connections. The chromium-based browser and also Firefox don't add Sec-WebSocket-Key into the headers during connection. We use the standard new WebSocket() to connect with the server.

Connection

Missing header Sec-WebSocket-Key header Missing header

Funny thing is that when I open a new incognito window I can create a connection but after some fetch() request if I will try to make another connection it will fail - missing Sec-Websocket-Key header.

  1. First WebSocket connection - success First WebSocket connection - success

  2. Fetch request - app health status enter image description here

  3. Failed WebSockect connection after a fetch request Failed WebSockect connection after a fetch request Second WebSocket connection - missing Sec-WebSocket-Key Second WebSocket connection details - missing Sec-Websocket-Key

Nginx config for /ws.

    location ^~ /ws {                                                                                                                      
        proxy_http_version 1.1;                                                                     
        proxy_set_header Upgrade $http_upgrade;                     
        proxy_set_header Connection "upgrade";                                                               
        proxy_set_header Host $http_host;                           
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;            
        proxy_pass http://backend;  
    }                           

Has anyone encountered a similar problem?

Checked in Google Chrome Version 96.0.4664.93 and Firefox 95.0.1 Windows, Linux and Mac.

MacOS & Safari works.

1 Answers

The problem is probably in the HTTP2 implementation in Firefox & Chrome (Safari works OK). We were digging for three days and finally realized that after disabling the HTTP2 issue disappeared.

This is the response from DigitalOcean technical support:

We had recently enabled support for Websockets over HTTP2 (RFC 8441). This adds support for browsers to reuse an existing HTTP2 connection and will allow tunneling of WebSocket connections over an HTTP2 stream. As part of an immediate fix we have disabled this functionality which informs browsers to create Websockets over HTTP1.1 (RFC 6455). We believe the bug is actually within Chrome/Firefox but further testing is necessary to track down the issue. To our knowledge the LB wasn't the issue as it was the browser that was not including the required header Sec-WebSocket-Key.

Related