gorilla/websocket · error
websocket: internal error, unexpected text or binary in Read
Error message
websocket: internal error, unexpected text or binary in Reader
What it means
This internal consistency-check error occurs inside the message Reader loop: advanceFrame returned a TextMessage or BinaryMessage frame type in a state where only control frames or continuation frames were expected. It indicates an internal state-machine bug, since ReadMessage/NextReader should never surface data frames through this path.
Source
Thrown at conn.go:1085
rem -= int64(n)
_ = c.setReadRemaining(rem) // rem is guaranteed to be >= 0
if c.readRemaining > 0 && c.readErr == io.EOF {
c.readErr = errUnexpectedEOF
}
return n, c.readErr
}
if c.readFinal {
c.messageReader = nil
return 0, io.EOF
}
frameType, err := c.advanceFrame()
switch {
case err != nil:
c.readErr = err
case frameType == TextMessage || frameType == BinaryMessage:
c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
}
}
err := c.readErr
if err == io.EOF && c.messageReader == r {
err = errUnexpectedEOF
}
return 0, err
}
func (r *messageReader) Close() error {
return nil
}
// ReadMessage is a helper method for getting a reader using NextReader and
// reading from that reader to a buffer.
func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
var r io.ReaderView on GitHub (pinned to e064f32e36)
Solutions
- Use the official gorilla/websocket release instead of a modified fork
- If you fork the library, review the advanceFrame/Reader state machine so data frame types are consumed in the correct state
- Check whether the connection is being shared concurrently between goroutines, which can corrupt the read state; use one reader goroutine per connection
Defensive patterns
Strategy: try-catch
Prevention
- Use official library releases
- Never share a Conn's read side between goroutines
- Report internal errors upstream with a reproduction
When it happens
Trigger: Calling Read()/NextReader and having the internal readErr state machine receive a text/binary frame type it believed it already consumed; not reachable through correct library internals.
Common situations: Custom forks of gorilla/websocket with modified frame-advance logic; virtually never seen with the stock library.
Related errors
- websocket: internal error, unexpected bytes at end of flate
- websocket: internal error, extra used in client mode
- websocket: bad handshake
- websocket: invalid compression negotiation
- malformed ws or wss URL
AI-assisted analysis of gorilla/websocket@e064f32e36 (2026-08-31).
Data as JSON: /api/errors/230742a4fe46b391.
Report an issue: GitHub.