How HTTP Works

Request header

> Sec-Websocket-Key: dGhlIHNhbXBsZSBub25jZQ==

Sec-WebSocket-Key

Learn how the Sec-WebSocket-Key header provides a random key for WebSocket handshake validation. Understand the upgrade process and security implications.

Reviewed 2 min readadvanced2 sourcesTry itMarkdown
Direction
Request
Category
WebSocket
Spec
RFC 6455 §4.1
JS can set it
No: forbidden header name
On this page

TL;DR: Sec-WebSocket-Key is a random 16-byte value, base64-encoded, that the client sends when opening a WebSocket. The server hashes it with a fixed GUID and sends the result back in Sec-WebSocket-Accept, proving it understood the upgrade. It’s not a password or an encryption key, and browsers set it for you.

What The Header Is Doing

This example HTTP/1.1 request uses the sample key from RFC 6455:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Real clients pick a new random value for every connection. Decoded from base64, it has to be exactly 16 bytes, as required by RFC 6455 §§4.1–4.2.1.

Because the accept value depends on this exact key, an unrelated HTTP response can’t satisfy the handshake by accident. That’s all it does. It doesn’t authenticate anyone or tell you the peer is trustworthy; TLS and your application’s own authentication handle those jobs.

The Important Practical Consequence

In the browser, you open a socket with new WebSocket(url); you can’t build the upgrade yourself with fetch(). The browser generates the key. The Fetch Standard reserves headers beginning with Sec-, and the WebSockets Standard defines handshake generation.

What Server Code Has To Do

Validate the whole opening request before accepting it. To compute the accept value, append the public GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 to the base64 text, not to the decoded 16 bytes, then SHA-1 hash and base64-encode the result.

Generate a diagnostic key in Node:

node --input-type=module -e 'import { randomBytes } from "node:crypto"; console.log(randomBytes(16).toString("base64"))'

That only prints a value; no request goes anywhere. A real client also has to validate the upgrade response and handle framing, masking, and closing the connection.

What To Check During Debugging

Look at the request and response side by side. Check that the key decodes to 16 bytes and that the response has status 101, Upgrade: websocket, Connection: Upgrade, and the matching accept value. If the accept value is missing or wrong, the client has to fail the handshake under RFC 6455 §4.1.

Generate a fresh key per connection; the RFC sample is for testing only. And if a proxy rewrites the key, the server’s answer won’t match what the client expects, so the handshake fails.

For a captured key, check the decoded length in Node:

node -e 'console.log(Buffer.from("dGhlIHNhbXBsZSBub25jZQ==", "base64").length)'

The RFC sample prints 16. That’s a sanity check rather than full validation: Node’s base64 decoder accepts some inputs the WebSocket grammar doesn’t allow. Leave real handshake validation to your WebSocket library.

Frequently asked questions

What is Sec-WebSocket-Key?

It is a random 16-byte value, base64-encoded, that the client generates fresh for every WebSocket opening handshake. The server uses it to prove it understood the upgrade request.

How does the server respond to Sec-WebSocket-Key?

The server appends the fixed WebSocket GUID to the base64 key text, takes the SHA-1 hash, and returns it base64-encoded in Sec-WebSocket-Accept. That proves the handshake worked; it says nothing about who the user is.

Why is Sec-WebSocket-Key needed?

It lets the client confirm that the server really processed its WebSocket handshake, so an ordinary HTTP response, say from a cache or a server that knows nothing about WebSockets, can never be mistaken for a successful upgrade.

Can I set Sec-WebSocket-Key manually?

Not in a browser. The WebSocket API generates it for you, and JavaScript has no way to set it.

Sources

  1. MDN Web Docs: Sec-WebSocket-Keydeveloper.mozilla.org
  2. RFC 6455: WebSocket Protocolrfc-editor.org

Keep going

Browse /search