golang/go · error
gzip.ErrHeader
gzip.ErrHeader
Error message
gzip: invalid header
What it means
Returned when the leading bytes of a candidate GZIP stream fail RFC 1952 header validation: magic bytes must be 0x1f 0x8b, the compression method (CM) must be 8 (deflate), reserved FLG bits must be clear, and the MTIME/XFL/OS fields and any optional FEXTRA/FNAME/FCOMMENT/FHCRC sections must parse cleanly. Any deviation aborts the reader before deflate decoding starts.
Source
Thrown at src/compress/gzip/gunzip.go:34
"time"
)
const (
gzipID1 = 0x1f
gzipID2 = 0x8b
gzipDeflate = 8
flagText = 1 << 0
flagHdrCrc = 1 << 1
flagExtra = 1 << 2
flagName = 1 << 3
flagComment = 1 << 4
)
var (
// ErrChecksum is returned when reading GZIP data that has an invalid checksum.
ErrChecksum = errors.New("gzip: invalid checksum")
// ErrHeader is returned when reading GZIP data that has an invalid header.
ErrHeader = errors.New("gzip: invalid header")
)
var le = binary.LittleEndian
// noEOF converts io.EOF to io.ErrUnexpectedEOF.
func noEOF(err error) error {
if err == io.EOF {
return io.ErrUnexpectedEOF
}
return err
}
// The gzip file stores a header giving metadata about the compressed file.
// That header is exposed as the fields of the [Writer] and [Reader] structs.
//
// Strings must be UTF-8 encoded and may only contain Unicode code points
// U+0001 through U+00FF, due to limitations of the GZIP file format.
type Header struct {View on GitHub (pinned to b6b368adc5)
Solutions
- Sniff the first two bytes before wrapping: a real GZIP stream starts with 0x1f 0x8b.
- Pick the correct decoder for the actual format: use compress/flate for raw deflate, compress/zlib for zlib, or archive/zip for zip.
- If the data is plaintext, drop the gzip wrapper entirely and read the underlying io.Reader directly.
- Re-check HTTP Content-Encoding / Transfer-Encoding; many servers omit `gzip` when they send identity responses.
- For concatenated streams, loop with Multireader semantics or call Reset between members rather than assuming one header covers everything.
Example fix
// before
gr, err := gzip.NewReader(resp.Body)
// "gzip: invalid header" on a plaintext response
// after: sniff magic bytes and degrade gracefully
br := bufio.NewReader(resp.Body)
hdr, _ := br.Peek(2)
var r io.Reader = br
if bytes.Equal(hdr, []byte{0x1f, 0x8b}) {
gr, err := gzip.NewReader(br)
if err != nil { return err }
defer gr.Close()
r = gr
}
io.Copy(out, r) Defensive patterns
Strategy: validation
Validate before calling
func isGzipStream(r io.Reader) (io.Reader, bool) {
br := bufio.NewReader(r)
b, err := br.Peek(2)
if err != nil { return br, false }
return br, b[0] == 0x1f && b[1] == 0x8b
}
// Usage:
// peeked, ok := isGzipStream(body)
// if !ok { /* read raw */ } Try / catch
gr, err := gzip.NewReader(r)
if err != nil {
if errors.Is(err, gzip.ErrHeader) {
// Fall back to raw read or try other decoders (zlib, flate).
return tryOtherFormats(r)
}
return err
} Prevention
- Always sniff the 0x1f 0x8b magic before wrapping a reader as gzip.
- Match Content-Encoding / Content-Type to your decoder choice.
- For multipart bodies, parse the part boundary before attempting gzip decode.
- Write a unit test that feeds each of {gzip, zlib, raw deflate, plaintext} through your pipeline.
When it happens
Trigger: Calling gzip.NewReader (or Read on a reset reader) on a stream whose first ten bytes are not a valid GZIP header. Common offenders: feeding raw deflate (no gzip wrapper), feeding zlib, feeding an uncompressed file, or feeding a zip archive whose first entry happens to look binary.
Common situations: Pointing the reader at a file with the wrong extension (.gz that is actually plaintext, or a .tar that was never gzipped), double-compression where one layer is stripped, content-encoding negotiation bugs in HTTP clients (server sent identity but client assumed gzip), or reading from a multipart body at the wrong offset.
Related errors
- gzip.Write: Extra data is too large
- gzip.Write: non-Latin-1 header string
- zlib.ErrHeader
- gzip.ErrChecksum
- zlib.ErrDictionary
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c3c1d41d65a62b4f.
Report an issue: GitHub.