- Description of issue
I wasted several hours today trying to figure out why MintWebSocket.upgrade/5 was failing when connecting to a websocket at wss://demo.rss.chat/
I noted that other websocket clients were succeeding and went to compare the headers that were sent at the upgrade request.
This particular server rejects the standard Mint.WebSocket.upgrade/5 call with a status 400 and a somewhat misleading message:
HTTP/1.1 400 Bad Request
Alt-Svc: h3=":443"; ma=2592000
Content-Type: text/html
Date: Mon, 17 Aug 2026 00:13:04 GMT
Server: Caddy
Transfer-Encoding: chunked
34
This HTTP server can't handle WebSocket connections.
I finally tracked down the issue to the fact that MintWebSocket.upgrade/5 sends a Connection header with the value "upgrade" in lowercase. When that is changed to "Upgrade" (capitalized), the socket is upgraded successfully.
- Possible fix
Mint.WebSocket.Utils.headers/2 shows the following:
# header names are written in their conventional casing: Mint lowercases them
# unless the connection was opened with `case_sensitive_headers: true`
def headers({:http1, nonce}, extensions) when is_binary(nonce) do
[
{"Upgrade", "websocket"},
{"Connection", "upgrade"},
{"Sec-WebSocket-Version", "13"},
{"Sec-WebSocket-Key", nonce},
{"Sec-WebSocket-Extensions", extension_string(extensions)}
]
|> Enum.reject(fn {_k, v} -> v == "" end)
end
When I changed {"Connection", "upgrade"} to {"Connection", "Upgrade"} (capitalized), the connection succeeded. All of the non-normative examples in RFC6445 section 1.1 and 1.2 show the handshake headers using the capitalized "Upgrade" and the lowercase "websocket".
I believe that Mint.WebSocket.Utils.headers/2 should return the capitalized version.
For this particular server I was able to connect by supplying my own {"Connection", "Upgrade"} header (so that both values, "upgrade" and "Upgrade", are sent to the server in that order), but I don't know if that will work generally or not.
I wasted several hours today trying to figure out why
MintWebSocket.upgrade/5was failing when connecting to a websocket at wss://demo.rss.chat/I noted that other websocket clients were succeeding and went to compare the headers that were sent at the upgrade request.
This particular server rejects the standard
Mint.WebSocket.upgrade/5call with a status 400 and a somewhat misleading message:I finally tracked down the issue to the fact that
MintWebSocket.upgrade/5sends a Connection header with the value "upgrade" in lowercase. When that is changed to "Upgrade" (capitalized), the socket is upgraded successfully.Mint.WebSocket.Utils.headers/2shows the following:When I changed
{"Connection", "upgrade"}to{"Connection", "Upgrade"}(capitalized), the connection succeeded. All of the non-normative examples in RFC6445 section 1.1 and 1.2 show the handshake headers using the capitalized "Upgrade" and the lowercase "websocket".I believe that
Mint.WebSocket.Utils.headers/2should return the capitalized version.For this particular server I was able to connect by supplying my own
{"Connection", "Upgrade"}header (so that both values, "upgrade" and "Upgrade", are sent to the server in that order), but I don't know if that will work generally or not.