{"record":{"id":"b5f4fb2bebf8a157","repo":"golang/go","slug":"zlib-errdictionary","errorCode":"zlib.ErrDictionary","errorMessage":"zlib: invalid dictionary","messagePattern":"zlib: invalid dictionary","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/compress/zlib/reader.go","lineNumber":45,"sourceCode":"\t\"bufio\"\n\t\"compress/flate\"\n\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.","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/compress/zlib/reader.go#L27-L63","documentation":"Returned when a zlib stream's FDICT flag is set (the stream mandates a preset dictionary) but the caller used NewReader without a dictionary, or when the supplied dictionary's Adler-32 does not match the DICTID field embedded in the stream header. The check happens in the reader's Read/Reset path before deflate decoding begins.","triggerScenarios":"Calling zlib.NewReader on a stream produced with a preset dictionary while providing none; or calling NewReaderDict with a dictionary whose bytes differ from the producer's dictionary (Adler-32 mismatch).","commonSituations":"HTTP `Accept-Encoding`-style pre-shared dictionaries (e.g., SDCH or shared compression dictionaries), DEFLATE64 with preset dictionaries, decoding a payload compressed by a different service that owns a dict you do not have, or a dict regenerated from a non-deterministic source.","solutions":["Use zlib.NewReaderDict(r, dict) with the exact dictionary bytes the producer used.","Ensure the dictionary is byte-identical — Adler-32 is sensitive to a single byte difference; do not re-serialize it.","Distribute dictionaries via content addressing (hash) so producer and consumer load the same artifact.","If you do not have the dictionary, ask the producer to disable preset-dictionary mode (FDICT=0)."],"exampleFix":"// before\nzr, err := zlib.NewReader(r) // stream has FDICT set\n// \"zlib: invalid dictionary\"\n\n// after: supply the preset dictionary\nzr, err := zlib.NewReaderDict(r, sharedDict)\nif err != nil { return err }\ndefer zr.Close()","handlingStrategy":"validation","validationCode":"import \"hash/adler32\"\n\n// If you have a candidate dictionary, verify its Adler-32 matches the\n// DICTID embedded in the stream (bytes 2..5, big-endian, when FDICT set).\nfunc dictMatches(streamHead []byte, dict []byte) error {\n    if len(streamHead) < 6 { return errors.New(\"short header\") }\n    if streamHead[1]&0x20 == 0 { return nil } // FDICT not set\n    want := binary.BigEndian.Uint32(streamHead[2:6])\n    if adler32.Checksum(dict) != want {\n        return zlib.ErrDictionary\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"zr, err := zlib.NewReaderDict(r, dict)\nif err != nil {\n    if errors.Is(err, zlib.ErrDictionary) {\n        // Load the correct dictionary artifact or disable FDICT on the producer.\n    }\n    return err\n}","preventionTips":["Distribute dictionaries via content-hash addressing.","Never re-serialize dictionaries — Adler-32 is sensitive to single bytes.","Document the FDICT contract clearly for any peer service producing streams."],"tags":["zlib","compression","dictionary","header-validation","rfc-1950"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}