{"record":{"id":"352b2ee9bef7a699","repo":"gorilla/websocket","slug":"websocket-internal-error-unexpected-bytes-at-end","errorCode":null,"errorMessage":"websocket: internal error, unexpected bytes at end of flate stream","messagePattern":"websocket: internal error, unexpected bytes at end of flate stream","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compression.go","lineNumber":117,"sourceCode":"\tp  *sync.Pool\n}\n\nfunc (w *flateWriteWrapper) Write(p []byte) (int, error) {\n\tif w.fw == nil {\n\t\treturn 0, errWriteClosed\n\t}\n\treturn w.fw.Write(p)\n}\n\nfunc (w *flateWriteWrapper) Close() error {\n\tif w.fw == nil {\n\t\treturn errWriteClosed\n\t}\n\terr1 := w.fw.Flush()\n\tw.p.Put(w.fw)\n\tw.fw = nil\n\tif w.tw.p != [4]byte{0, 0, 0xff, 0xff} {\n\t\treturn errors.New(\"websocket: internal error, unexpected bytes at end of flate stream\")\n\t}\n\terr2 := w.tw.w.Close()\n\tif err1 != nil {\n\t\treturn err1\n\t}\n\treturn err2\n}\n\ntype flateReadWrapper struct {\n\tfr io.ReadCloser\n}\n\nfunc (r *flateReadWrapper) Read(p []byte) (int, error) {\n\tif r.fr == nil {\n\t\treturn 0, io.ErrClosedPipe\n\t}\n\tn, err := r.fr.Read(p)\n\tif err == io.EOF {","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/gorilla/websocket/blob/e064f32e3674d9d79a8fd417b5bc06fa5c6cad8f/compression.go#L99-L135","documentation":"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.","triggerScenarios":"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.","commonSituations":"Very rare; encountered when mixing gorilla/websocket versions/patches, running modified compression code, or a genuine library bug in permessage-deflate handling.","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"],"exampleFix":"// before\ndialer := websocket.Dialer{EnableCompression: true}\n// after (workaround)\ndialer := websocket.Dialer{}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"unexpected bytes at end of flate stream\") {\n    log.Error(\"compression state corrupted; reconnecting without compression\")\n    dialer.EnableCompression = false\n    return reconnect(dialer)\n}","preventionTips":["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"],"tags":["websocket","compression","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e064f32e3674d9d79a8fd417b5bc06fa5c6cad8f","analyzedAt":"2026-08-31T12:40:58.222Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}