gorilla/websocket · error
websocket: read limit exceeded
Error message
websocket: read limit exceeded
What it means
ErrReadLimit is returned when an incoming message exceeds the limit set by Conn.SetReadLimit. It surfaces from the read path (setReadRemaining) as soon as the remaining message size is known to exceed the limit. This protects the application from memory exhaustion via oversized frames/messages.
Source
Thrown at conn.go:90
// function to format a close message payload.
CloseMessage = 8
// PingMessage denotes a ping control message. The optional message payload
// is UTF-8 encoded text.
PingMessage = 9
// PongMessage denotes a pong control message. The optional message payload
// is UTF-8 encoded text.
PongMessage = 10
)
// ErrCloseSent is returned when the application writes a message to the
// connection after sending a close message.
var ErrCloseSent = errors.New("websocket: close sent")
// ErrReadLimit is returned when reading a message that is larger than the
// read limit set for the connection.
var ErrReadLimit = errors.New("websocket: read limit exceeded")
// netError satisfies the net Error interface.
type netError struct {
msg string
temporary bool
timeout bool
}
func (e *netError) Error() string { return e.msg }
func (e *netError) Temporary() bool { return e.temporary }
func (e *netError) Timeout() bool { return e.timeout }
// CloseError represents a close message.
type CloseError struct {
// Code is defined in RFC 6455, section 11.7.
Code int
// Text is the optional text payload.View on GitHub (pinned to e064f32e36)
Solutions
- Raise the limit via conn.SetReadLimit to accommodate legitimate message sizes
- Send large payloads in chunks or out-of-band (HTTP upload + reference in the message)
- On ErrReadLimit, close the connection with CloseMessageTooBig (1009) per spec
- Validate message size expectations server-side and log offending clients
Example fix
// before
conn.SetReadLimit(4096)
msg, _, err := conn.ReadMessage() // fails for big payloads
// after
conn.SetReadLimit(1 << 20) // 1 MiB
msg, _, err := conn.ReadMessage()
if errors.Is(err, websocket.ErrReadLimit) {
conn.Close() // or send CloseMessageTooBig
return
} Defensive patterns
Strategy: type-guard
Validate before calling
conn.SetReadLimit(maxAllowedBytes) // choose from known payload limits
guard := func(n int) error { if n > maxAllowedBytes { return errors.New("payload too large") }; return nil } Type guard
func isReadLimit(err error) bool {
return errors.Is(err, websocket.ErrReadLimit)
} Try / catch
_, msg, err := conn.ReadMessage()
if err != nil {
if errors.Is(err, websocket.ErrReadLimit) {
websocket.CloseMessage... // send close 1009 and drop the peer
conn.WriteControl(websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseMessageTooBig, "too big"),
time.Now().Add(time.Second))
return
}
return err
} Prevention
- Set an explicit read limit on every connection to bound memory use
- Match the limit to the largest legitimate message plus headroom
- Chunk large payloads or move them out-of-band instead of raising limits indefinitely
When it happens
Trigger: Calling conn.ReadMessage/NextReader when the peer sends a message larger than the configured read limit (default limit is unlimited unless SetReadLimit is called; if set, exceeding it returns this error).
Common situations: Peer (or attacker) sending huge payloads; limit set too low for legitimate large messages (e.g. file uploads over a message); limit configured from a config value mismatched with production traffic sizes.
Related errors
- websocket: bad handshake
- websocket: invalid compression negotiation
- malformed ws or wss URL
- websocket: duplicate header not allowed:
- websocket: protocol %q was given but is not supported;sharin
AI-assisted analysis of gorilla/websocket@e064f32e36 (2026-08-31).
Data as JSON: /api/errors/c667a46fc32fbc33.
Report an issue: GitHub.