golang/go · error
gzip.Write: Extra data is too large
Error message
gzip.Write: Extra data is too large
What it means
gzip.Writer.writeBytes rejects any byte slice longer than 0xffff (65535) because the GZIP FEXTRA field stores its length in a 2-byte little-endian XLEN prefix. writeBytes is used internally when emitting the Header.Extra bytes during the next Write/Flush call, so the error propagates from those methods.
Source
Thrown at src/compress/gzip/gzip.go:103
},
w: w,
level: level,
compressor: compressor,
}
}
// Reset discards the [Writer] z's state and makes it equivalent to the
// result of its original state from [NewWriter] or [NewWriterLevel], but
// writing to w instead. This permits reusing a [Writer] rather than
// allocating a new one.
func (z *Writer) Reset(w io.Writer) {
z.init(w, z.level)
}
// writeBytes writes a length-prefixed byte slice to z.w.
func (z *Writer) writeBytes(b []byte) error {
if len(b) > 0xffff {
return errors.New("gzip.Write: Extra data is too large")
}
le.PutUint16(z.buf[:2], uint16(len(b)))
_, err := z.w.Write(z.buf[:2])
if err != nil {
return err
}
_, err = z.w.Write(b)
return err
}
// writeString writes a UTF-8 string s in GZIP's format to z.w.
// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
func (z *Writer) writeString(s string) (err error) {
// GZIP stores Latin-1 strings; error if non-Latin-1; convert if non-ASCII.
needconv := false
for _, v := range s {
if v == 0 || v > 0xff {
return errors.New("gzip.Write: non-Latin-1 header string")View on GitHub (pinned to b6b368adc5)
Solutions
- Trim or chunk the Extra payload so len(Header.Extra) <= 65535 bytes.
- Move the oversized metadata out of the GZIP header into a sidecar file or a separate framing layer.
- If you need arbitrary-length metadata, define your own container format that wraps the gzip stream rather than abusing FEXTRA.
- Validate the length once when assigning Header.Extra rather than discovering the error on every Write.
Example fix
// before
gz.Header.Extra = bigMetadataBlob // > 64 KiB
// "gzip.Write: Extra data is too large"
// after: cap and spill
const maxExtra = 0xffff
if len(bigMetadataBlob) > maxExtra {
return fmt.Errorf("metadata %d bytes exceeds gzip FEXTRA limit %d",
len(bigMetadataBlob), maxExtra)
}
gz.Header.Extra = bigMetadataBlob Defensive patterns
Strategy: validation
Validate before calling
const gzipMaxExtra = 0xffff
func setExtra(h *gzip.Header, extra []byte) error {
if len(extra) > gzipMaxExtra {
return fmt.Errorf("extra field %d bytes exceeds %d", len(extra), gzipMaxExtra)
}
h.Extra = extra
return nil
} Try / catch
gz.Header.Extra = blob
if _, err := gz.Write(nil); err != nil { // or first Write
if strings.Contains(err.Error(), "Extra data is too large") {
return oversizeExtraError{len: len(blob)}
}
} Prevention
- Cap Header.Extra at 64 KiB at the boundary that produces it.
- Move large metadata to a sidecar file or wrapper framing.
- Add a unit test that exercises Extra at boundary lengths (0, 0xffff, 0xffff+1).
When it happens
Trigger: Setting gz.Header.Extra (or passing Extra via the Writer zero-value before Reset) to a slice whose length exceeds 65535, then calling Write, Flush, or Close on the writer. The check fires before any byte is written to the underlying writer.
Common situations: Embedding a metadata blob, JSON manifest, signing payload, or trace context in the GZIP extra field and exceeding the 64 KiB ceiling; copying Extra from a different format that has no such limit; appending authentication tags without bound.
Related errors
- gzip.ErrHeader
- gzip.Write: non-Latin-1 header string
- gzip.ErrChecksum
- lzw: input byte too large for the litWidth
- lzw: unknown order
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a5748d09e6f7a0cd.
Report an issue: GitHub.