gorilla/websocket · error
websocket: internal error, unexpected bytes at end of flate
Error message
websocket: internal error, unexpected bytes at end of flate stream
What it means
This internal invariant check fires in flateWriter.Close (compression.go) when the flushed flate stream does not end with the expected sync marker bytes 0x00 0x00 0xff 0xff. It means the flate writer state is corrupted or the library's compression bookkeeping is inconsistent. It is a bug indicator, not an expected runtime condition.
Source
Thrown at compression.go:117
p *sync.Pool
}
func (w *flateWriteWrapper) Write(p []byte) (int, error) {
if w.fw == nil {
return 0, errWriteClosed
}
return w.fw.Write(p)
}
func (w *flateWriteWrapper) Close() error {
if w.fw == nil {
return errWriteClosed
}
err1 := w.fw.Flush()
w.p.Put(w.fw)
w.fw = nil
if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
}
err2 := w.tw.w.Close()
if err1 != nil {
return err1
}
return err2
}
type flateReadWrapper struct {
fr io.ReadCloser
}
func (r *flateReadWrapper) Read(p []byte) (int, error) {
if r.fr == nil {
return 0, io.ErrClosedPipe
}
n, err := r.fr.Read(p)
if err == io.EOF {View on GitHub (pinned to e064f32e36)
Solutions
- Upgrade gorilla/websocket to the latest release
- Disable compression (EnableCompression = false / don't accept the extension) as a workaround
- If reproducible on the latest version, file a bug with a minimal reproducer
Example fix
// before
dialer := websocket.Dialer{EnableCompression: true}
// after (workaround)
dialer := websocket.Dialer{} Defensive patterns
Strategy: fallback
Try / catch
if err != nil && strings.Contains(err.Error(), "unexpected bytes at end of flate stream") {
log.Error("compression state corrupted; reconnecting without compression")
dialer.EnableCompression = false
return reconnect(dialer)
} Prevention
- Pin and regularly update gorilla/websocket versions
- Do not patch or vendor-modify compression code paths
- Disable compression when a message is a compressed-message bug trigger until fixed
When it happens
Trigger: Writing a compressed message with compression enabled and closing the flate writer when the internal trailer bytes don't match the permessage-deflate empty-block trailer — essentially only from library-internal state corruption or a version mismatch in compression code paths.
Common situations: Very rare; encountered when mixing gorilla/websocket versions/patches, running modified compression code, or a genuine library bug in permessage-deflate handling.
Related errors
- websocket: invalid compression negotiation
- websocket: internal error, extra used in client mode
- websocket: internal error, unexpected text or binary in Read
- websocket: invalid compression level
- websocket: bad handshake
AI-assisted analysis of gorilla/websocket@e064f32e36 (2026-08-31).
Data as JSON: /api/errors/352b2ee9bef7a699.
Report an issue: GitHub.