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

  1. Raise the limit via conn.SetReadLimit to accommodate legitimate message sizes
  2. Send large payloads in chunks or out-of-band (HTTP upload + reference in the message)
  3. On ErrReadLimit, close the connection with CloseMessageTooBig (1009) per spec
  4. 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

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


AI-assisted analysis of gorilla/websocket@e064f32e36 (2026-08-31). Data as JSON: /api/errors/c667a46fc32fbc33. Report an issue: GitHub.