Also available in: Español · Português · Français · العربية
WebSocket Close Codes
The full IANA list, with the codes RFC 6455 forbids putting in a Close frame marked as what they are — including the one you are probably here for.
What is a WebSocket close code?
When a WebSocket connection ends cleanly, the side closing it sends a Close frame carrying a four-digit number that says why. 1000 means the connection finished normally, 1001 means the endpoint is going away, 1011 means the server hit an unexpected condition. Your client library surfaces that number, and it is usually the only clue you get about what went wrong.
The numbers are managed by IANA in a registry of twenty-four rows — sixteen individual codes in the 1000s, a few assignments in the 3000s, and several spans that are unassigned or set aside for you to define yourself. This page lists all of them, searchable, and a number with no row of its own resolves to the span it falls in.
It also marks something the registry cannot. Three of those codes are not messages at all, and one of them is almost certainly the reason you are reading this.
How to use it
- Type the number your client reported. The matching row comes up first. If the number has no row of its own — anything in the 2000s, or a private-use code in the 4000s — you get the range that covers it instead of nothing.
- Read the state, not just the meaning. Every row says whether a code can actually be sent. That is the column that tells you whether the other side chose it or your own library invented it.
- Search by words too. Typing part of a meaning works — abnormal, policy, restart — which is faster when you half-remember the phrase but not the number.
1006 is not a message from the server
This is the part worth carrying away. Three codes — 1005, 1006 and 1015 — each carry a sentence in RFC 6455 saying they are reserved values that must not be set as a status code in a Close control frame. They are not things an endpoint can send. They exist so that a library has something to report when there is nothing to report.
1006 means your client never received a Close frame at all. Nobody chose it and nobody sent it; the library filled it in to describe a connection that simply stopped. So the cause is below the protocol — a dropped TCP connection, a proxy or load balancer that timed the socket out, a network that went away, or a handshake that never completed. Looking through your server logs for whatever sent 1006 is looking for someone who does not exist.
1005 is the same idea one step along: a Close frame did arrive, but it carried no status code at all, which is legal. And 1015 reports that TLS failed before there was a WebSocket to speak of. All three are your own side describing its situation, in the vocabulary the specification set aside for exactly that.
There is a fourth state that is easy to lump in with them and should not be. 1004 is reserved with its meaning undefined, and it carries no clause forbidding it from being sent — it is simply a number nobody has given a job to. Four states, then, where a table copied from the registry shows two.
What the registry does and does not tell you
IANA publishes five columns for each row: the status code, its meaning, a contact, a reference and a change controller. There is no column for whether a code may be sent, and there is no way to add one without changing the registry's schema. The distinction lives only in the prose of RFC 6455 section 7.4.1.
That is why so many published tables lose it. 1000 and 1006 are the same shape of row, with the same meaning field and the same reference to the same RFC, so a table generated from the registry renders them identically. Nothing in the data says one is a message and the other is a local fiction.
Three codes have a provenance worth showing rather than tidying away. 1012, 1013 and 1014 — service restart, try again later, and a gateway error deliberately mirroring HTTP 502 — were not defined by a standards document at all. They were registered by a message to a mailing list, and the registry's reference column links to that message rather than to an RFC. They work, they are widely implemented, and they got there by a different route from everything around them.
The honest limitation of a page like this is that it is a snapshot of a registry that can gain rows. What guards against it going quietly stale is that the generator refuses to build unless RFC 6455 still contains the exact sentence it attributes to each of the three never-sent codes — so the classification cannot drift away from its source without the build failing.
Why is it free?
The whole list is in the page, and searching it happens in your browser. There is nothing to run on a server and no reason to ask you for an account.
Nothing you type is uploaded, stored or logged. You are usually here with a code out of a production log, and the reliable way to keep that private is never to receive it.