Troubleshooting /

WebSocket close codes: what 1000 to 1015 mean

A plain-language reference for the status codes a WebSocket close event can carry, and what each one does and does not tell you.

In short: 1000 is the only clean close. 1001 to 1011 come from the peer and name a reason. 1005, 1006, and 1015 are never sent on the wire; the browser reports them locally when no close frame arrived, and 1006 in particular says only that the connection dropped, not why.

Last updated

Run a WebSocket check from this browser

The NetOkay test opens an echo endpoint, sends one message, and closes with 1000. The result shows the close code your browser observed.

Run the WebSocket test

Close codes 1000 to 1015

Codes 1000 to 1011 are defined in RFC 6455; 1012 to 1015 were added to the IANA registry afterwards. "Reserved for local use" means the code is set by the client library or browser, never received from the other end.

Code Name What it means
1000 Normal closure The purpose of the connection was fulfilled and one side closed on purpose. This is the only code a browser check treats as a clean end.
1001 Going away The endpoint is leaving: a server shutting down, or a browser navigating away from the page.
1002 Protocol error A frame violated the WebSocket protocol; usually a bug in one implementation or a middlebox altering frames.
1003 Unsupported data The endpoint received a data type it cannot accept, for example binary when only text is handled.
1004 Reserved Not assigned. Should never be sent.
1005 No status received Reserved for local use: the close frame carried no code. Browsers report it when the peer closed without a status.
1006 Abnormal closure Reserved for local use: the connection ended without a close frame at all. A dropped TCP connection, a proxy timeout, a crashed process, and a blocked handshake all produce 1006.
1007 Invalid payload A text frame contained data that was not valid UTF-8, or a message did not match the declared type.
1008 Policy violation The endpoint refused the message for a policy reason it does not want to name; often used for authorization failures.
1009 Message too big A message exceeded the size the endpoint is willing to process.
1010 Mandatory extension The client expected the server to negotiate an extension and it did not.
1011 Internal error The server hit an unexpected condition that stopped it from completing the request.
1012 Service restart The server is restarting; clients may reconnect after a short wait. Registered with IANA, not part of the original RFC 6455 list.
1013 Try again later The server is overloaded or otherwise temporarily unavailable. Registered with IANA.
1014 Bad gateway A gateway or proxy received an invalid response from the upstream server. Registered with IANA.
1015 TLS handshake failure Reserved for local use: the connection closed because the TLS handshake failed, for example a certificate the client did not trust.

Codes above 1015

What a close code can and cannot tell you

A code sent by the peer, such as 1008 or 1011, is a statement from that endpoint and is worth reading with its reason string. A locally generated code, above all 1006, only records that the connection ended without a close frame. It cannot distinguish a proxy idle timeout from a server crash, a firewall reset, or a network change, and it does not identify which hop dropped the connection. Treat 1006 as a prompt to look at both ends and every intermediary, not as a diagnosis.

The NetOkay echo endpoint itself closes with 1003 if it receives something other than text or binary data, 1009 if a message is larger than it accepts, and 1000 when its bounded time runs out.

Close code FAQ

Why do I only ever see 1006?

Because most failures happen before or outside the WebSocket protocol: a refused handshake, a dropped TCP connection, or a proxy that closed the socket without sending a close frame. The browser has nothing else to report. Check the HTTP handshake response and the server and proxy logs for the real reason.

Can I send my own close code?

Yes, but only 1000 or a code from 4000 to 4999 from browser code. Servers can send any registered code. Put the human-readable detail in the reason string, which is limited to 123 bytes.

Does 1006 mean my server crashed?

Not on its own. It means the connection ended without a close frame, which a crash causes, but so does a load balancer idle timeout or a laptop switching networks. If the server logs show a normal 1000 close that the client never received, look at the path between them.

Next: WebSocket connection failed: what to check walks through the failed stage, the original connection, and a retest.