golang/go · error
zlib: invalid compression level: %d
Error message
zlib: invalid compression level: %d
What it means
`zlib.NewWriterLevel` (and `NewWriterLevelDict`) reject a `level` outside `[HuffmanOnly(-2), BestCompression(9)]` before constructing the writer. This mirrors gzip/flate; zlib wraps DEFLATE so the level range is identical.
Source
Thrown at src/compress/zlib/writer.go:78
// Note that the exact bytes written to w are not covered by the Go 1
// compatibility promise. Callers, including tests, should not depend on the
// exact written bytes.
func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
return NewWriterLevelDict(w, level, nil)
}
// NewWriterLevelDict is like [NewWriterLevel] but specifies a dictionary to
// compress with.
//
// The dictionary may be nil. If not, its contents should not be modified until
// the Writer is closed.
//
// Note that the exact bytes written to w are not covered by the Go 1
// compatibility promise. Callers, including tests, should not depend on the
// exact written bytes.
func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error) {
if level < HuffmanOnly || level > BestCompression {
return nil, fmt.Errorf("zlib: invalid compression level: %d", level)
}
return &Writer{
w: w,
level: level,
dict: dict,
}, nil
}
// Reset clears the state of the [Writer] z such that it is equivalent to its
// initial state from [NewWriterLevel] or [NewWriterLevelDict], but instead writing
// to w.
func (z *Writer) Reset(w io.Writer) {
z.w = w
// z.level and z.dict left unchanged.
if z.compressor != nil {
z.compressor.Reset(w)
}
if z.digest != nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Clamp into range using the zlib constants (`zlib.DefaultCompression`, `zlib.BestSpeed`, `zlib.BestCompression`, `zlib.HuffmanOnly`).
- If unsure, use `zlib.DefaultCompression` (-1).
- Validate config-supplied integers at load time and reject with a clear message.
Example fix
// before zw, err := zlib.NewWriterLevel(out, 12) // after zw, err := zlib.NewWriterLevel(out, zlib.BestCompression)
Defensive patterns
Strategy: validation
Validate before calling
if level < zlib.HuffmanOnly || level > zlib.BestCompression {
level = zlib.DefaultCompression
} Try / catch
zw, err := zlib.NewWriterLevel(out, level)
if err != nil { zw = zlib.NewWriter(out) /* fall back to default */ } Prevention
- Use zlib.DefaultCompression if you have no specific need.
- Bound-check any config-derived level before calling NewWriterLevel.
When it happens
Trigger: Calling `zlib.NewWriterLevel(w, level)` with level < -2 or > 9; plumbing a config value on a different scale; passing the `zlib` level where a `flate` constant of a different numbering was intended (same range, but easy to mix).
Common situations: Settings files exposing a `level` field without bounds; defaulting to 0 thinking it means BestSpeed (0 is actually NoCompression/Store for flate-backed zlib — valid, but surprising — whereas the invalid values are < -2 or > 9).
Related errors
- flate: invalid compression level %d: want value in range [-2
- gzip: invalid compression level: %d
- cipher: the nonce can't have zero length
- lzw: litWidth %d out of range
- lzw: litWidth %d out of range
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/19a6a5e871a0b0e6.
Report an issue: GitHub.