{"record":{"id":"8ba0b025ac82f2a6","repo":"golang/go","slug":"zlib-errheader","errorCode":"zlib.ErrHeader","errorMessage":"zlib: invalid header","messagePattern":"zlib: invalid header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/compress/zlib/reader.go","lineNumber":47,"sourceCode":"\t\"encoding/binary\"\n\t\"errors\"\n\t\"hash\"\n\t\"hash/adler32\"\n\t\"io\"\n)\n\nconst (\n\tzlibDeflate   = 8\n\tzlibMaxWindow = 7\n)\n\nvar (\n\t// ErrChecksum is returned when reading ZLIB data that has an invalid checksum.\n\tErrChecksum = errors.New(\"zlib: invalid checksum\")\n\t// ErrDictionary is returned when reading ZLIB data that has an invalid dictionary.\n\tErrDictionary = errors.New(\"zlib: invalid dictionary\")\n\t// ErrHeader is returned when reading ZLIB data that has an invalid header.\n\tErrHeader = errors.New(\"zlib: invalid header\")\n)\n\ntype reader struct {\n\tr            flate.Reader\n\tdecompressor io.ReadCloser\n\tdigest       hash.Hash32\n\terr          error\n\tscratch      [4]byte\n}\n\n// Resetter resets a ReadCloser returned by [NewReader] or [NewReaderDict]\n// to switch to a new underlying Reader. This permits reusing a ReadCloser\n// instead of allocating a new one.\ntype Resetter interface {\n\t// Reset discards any buffered data and resets the Resetter as if it was\n\t// newly initialized with the given reader.\n\tReset(r io.Reader, dict []byte) error\n}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/compress/zlib/reader.go#L29-L65","documentation":"Returned when the zlib header (the two CMF/FLG bytes) fails RFC 1950 validation: CM must be 8 (deflate), CINFO must encode a window size <= 7 (32 KiB), the FCHECK field must make the two-byte header a multiple of 31, and FLEVEL is informational. Any deviation aborts before deflate decoding starts.","triggerScenarios":"Calling zlib.NewReader on data that is not a zlib stream — raw deflate (no header), gzip (different magic), an uncompressed payload, or a corrupt header where the FCHECK modulo-31 invariant fails.","commonSituations":"Mis-routing format choice: HTTP server sends gzip but client uses zlib.NewReader; websocket DEFLATE frames whose client-to-server/no-context-takeover stripping left a raw-deflate body; PNG IDAT chunks are zlib-wrapped but raw deflate is sometimes mis-attempted.","solutions":["Sniff the first byte: zlib's CMF low nibble is 0x08, and (CMF*256+FLG) % 31 == 0.","Use compress/flate for raw deflate, compress/gzip for gzip, or archive/zip for zip — match the decoder to the actual framing.","Re-check HTTP Content-Encoding; many servers send `gzip` even when the client advertised only `deflate`.","If you receive raw deflate from a peer, frame it yourself: prepend a valid zlib header or use flate.NewReader directly."],"exampleFix":"// before\nzr, err := zlib.NewReader(body) // body is raw deflate\n// \"zlib: invalid header\"\n\n// after: use the right reader for raw deflate\nfr := flate.NewReader(body)\ndefer fr.Close()\nio.Copy(out, fr)","handlingStrategy":"validation","validationCode":"func isZlibStream(r io.Reader) (io.Reader, bool) {\n    br := bufio.NewReader(r)\n    b, err := br.Peek(2)\n    if err != nil || len(b) < 2 { return br, false }\n    cmf, flg := b[0], b[1]\n    if cmf&0x0f != 8 { return br, false }\n    if (uint16(cmf)<<8 | uint16(flg)) % 31 != 0 { return br, false }\n    return br, true\n}","typeGuard":null,"tryCatchPattern":"zr, err := zlib.NewReader(r)\nif err != nil {\n    if errors.Is(err, zlib.ErrHeader) {\n        // Try gzip.NewReader or flate.NewReader as a fallback.\n        return tryOtherCodecs(r)\n    }\n    return err\n}","preventionTips":["Sniff CMF/FLG before constructing the reader.","Map Content-Encoding to the correct decoder explicitly.","Distinguish raw deflate from zlib-framed deflate at protocol design time."],"tags":["zlib","compression","header-validation","file-format","rfc-1950"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}