WebSocket close codes

July 8, 2024 ยท View on GitHub

Close code (uint16)IANA meaningReservedCustomUsage
0 - 999NoUnused
1000Normal ClosureSuccessful operation, connection not required anymore
1001Going AwayBrowser tab closing, graceful server shutdown
1002Protocol errorEndpoint received malformed frame
1003Unsupported DataEndpoint received unsupported frame (e.g. binary-only got text frame, ping/pong frames not handled properly)
1004NoUnused
1005No Status RcvdYesGot no close status but transport layer finished normally (e.g. TCP FIN but no previous CLOSE frame)
1006Abnormal ClosureYesTransport layer broke (e.g. couldn't connect, TCP RST)
1007Invalid frame payload dataData in endpoint's frame is not consistent (e.g. malformed UTF-8)
1008Policy ViolationGeneric code not applicable to any other (e.g. isn't 1003 nor 1009)
1009Message Too BigEndpoint won't process large message
1010Mandatory Ext.Client wanted extension(s) that server did not negotiate
1011Internal ErrorUnexpected server problem while operating
1012Service RestartServer/service is restarting
1013Try Again LaterTemporary server condition forced blocking client's application-based request
1014Bad gatewayServer acting as gateway/proxy got invalid response. Equivalent to HTTP 502
1015TLS handshakeYesTransport layer broke because TLS handshake failed
1016 - 2999-Extensions onlyUnused. Extensions or future spec can define them
3000 - 3999UndefinedYesAvailable for applications, registered first come first serve at IANA
3000UnauthorizedUndefinedYesEndpoint must be authorized to perform application-based request. Equivalent to HTTP 401
3003ForbiddenUndefinedYesEndpoint is authorized but has no permissions to perform application-based request. Equivalent to HTTP 403
3008TimeoutUndefinedYesEndpoint took too long to respond to application-based request. Equivalent to HTTP 408
4000 - 4999UndefinedYesAvailable for applications
  • Reserved means WebSocket implementation reports it to application, but per spec cannot be used as actual close code

  • Custom means undefined by spec. Application logic and/or WebSocket implementations are allowed to use it however they like, provided common sense that both endpoints will understand them

  • Transport layer is the protocol via which WebSocket messages get sent. Usually TCP or QUIC when over HTTP/3

  • Extensions are spec that changes how messages are sent. They aren't defined by WebSocket spec, implementations don't have to support them, and per RFC must have their details publicly available. One well used example is permessage-deflate

Relevant links: