gorilla/websocket · error
websocket: bad write message type
Error message
websocket: bad write message type
What it means
errBadWriteOpCode is returned when WriteMessage is called with an invalid message type — anything other than TextMessage (1), BinaryMessage (2), or an allowed control opcode the write path accepts. The library validates the messageType before writing.
Source
Thrown at conn.go:178
// IsUnexpectedCloseError returns boolean indicating whether the error is a
// *CloseError with a code not in the list of expected codes.
func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
if e, ok := err.(*CloseError); ok {
for _, code := range expectedCodes {
if e.Code == code {
return false
}
}
return true
}
return false
}
var (
errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
errBadWriteOpCode = errors.New("websocket: bad write message type")
errWriteClosed = errors.New("websocket: write closed")
errInvalidControlFrame = errors.New("websocket: invalid control frame")
)
// maskRand is an io.Reader for generating mask bytes. The reader is initialized
// to crypto/rand Reader. Tests swap the reader to a math/rand reader for
// reproducible results.
var maskRand = rand.Reader
// newMaskKey returns a new 32 bit value for masking client frames.
func newMaskKey() [4]byte {
var k [4]byte
_, _ = io.ReadFull(maskRand, k[:])
return k
}
func isControl(frameType int) bool {
return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessageView on GitHub (pinned to e064f32e36)
Solutions
- Pass only websocket.TextMessage or websocket.BinaryMessage as the first argument to WriteMessage
- Check for swapped arguments if using a variable message type
- Validate any externally-configured message type against the two allowed constants
Example fix
// before
if err := conn.WriteMessage(msgType, payload); err != nil { ... } // msgType is 0
// after
if msgType != websocket.TextMessage && msgType != websocket.BinaryMessage {
msgType = websocket.TextMessage
}
if err := conn.WriteMessage(msgType, payload); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
func validMessageType(t int) bool {
return t == websocket.TextMessage || t == websocket.BinaryMessage
} Type guard
func isTextOrBinary(t int) bool {
return t == websocket.TextMessage || t == websocket.BinaryMessage
} Try / catch
if !validMessageType(msgType) {
return fmt.Errorf("invalid message type %d", msgType)
}
if err := conn.WriteMessage(msgType, payload); err != nil {
return err
} Prevention
- Only use the websocket.TextMessage/BinaryMessage constants
- Watch argument order in WriteMessage(type, data) calls
- Don't map opcodes from other websocket libraries into gorilla constants
When it happens
Trigger: Calling conn.WriteMessage with a messageType constant that is not websocket.TextMessage or websocket.BinaryMessage (e.g. 0, 3-10, or an uninitialized variable), including accidentally passing the message payload's first byte as the type.
Common situations: Passing a dynamic/int messageType computed elsewhere, off-by-one or swapped arguments like WriteMessage(data, websocket.TextMessage), or reusing opcode constants from another WebSocket library.
Related errors
- malformed ws or wss URL
- websocket: invalid compression level
- websocket: bad handshake
- websocket: invalid compression negotiation
- websocket: duplicate header not allowed:
AI-assisted analysis of gorilla/websocket@e064f32e36 (2026-08-31).
Data as JSON: /api/errors/b434aaddb6824c27.
Report an issue: GitHub.