grpc/grpc-go · error

grpc: invalid gzip compression level: %d

Error message

grpc: invalid gzip compression level: %d

What it means

gzip.SetLevel rejects a compression level outside the standard library range [gzip.DefaultCompression (-1) .. gzip.BestCompression (9)]. The function documents that gzip.HuffmanOnly (-2) is also unsupported. The check is `level < gzip.DefaultCompression || level > gzip.BestCompression`.

Source

Thrown at encoding/gzip/gzip.go:60

	c.poolCompressor.New = func() any {
		return &writer{Writer: gzip.NewWriter(io.Discard), pool: &c.poolCompressor}
	}
	encoding.RegisterCompressor(c)
}

type writer struct {
	*gzip.Writer
	pool *sync.Pool
}

// SetLevel updates the registered gzip compressor to use the compression level specified (gzip.HuffmanOnly is not supported).
// NOTE: this function must only be called during initialization time (i.e. in an init() function),
// and is not thread-safe.
//
// The error returned will be nil if the specified level is valid.
func SetLevel(level int) error {
	if level < gzip.DefaultCompression || level > gzip.BestCompression {
		return fmt.Errorf("grpc: invalid gzip compression level: %d", level)
	}
	c := encoding.GetCompressor(Name).(*compressor)
	c.poolCompressor.New = func() any {
		w, err := gzip.NewWriterLevel(io.Discard, level)
		if err != nil {
			panic(err)
		}
		return &writer{Writer: w, pool: &c.poolCompressor}
	}
	return nil
}

func (c *compressor) Compress(w io.Writer) (io.WriteCloser, error) {
	z := c.poolCompressor.Get().(*writer)
	z.Writer.Reset(w)
	return z, nil
}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Use a level in [gzip.DefaultCompression, gzip.BestCompression] = [-1, 9]; common choices are gzip.DefaultCompression (-1), gzip.BestSpeed (1), gzip.BestCompression (9).
  2. If you want Huffman-only, know that this grpc gzip package deliberately does not support it; pick level 1 (BestSpeed) instead.
  3. Validate the level from config before calling SetLevel and fall back to a sane default (e.g. gzip.DefaultCompression).

Example fix

// before
if err := gzip.SetLevel(-2); err != nil { log.Fatal(err) } // invalid

// after
if err := gzip.SetLevel(gzip.BestSpeed); err != nil { log.Fatal(err) }
Defensive patterns

Strategy: validation

Validate before calling

import "compress/gzip"

func validGzipLevel(level int) error {
    if level < gzip.DefaultCompression || level > gzip.BestCompression {
        return fmt.Errorf("gzip level %d out of range [-1,9]", level)
    }
    return nil
}

Try / catch

if err := gzip.SetLevel(level); err != nil {
    return fmt.Errorf("bad gzip level %d: %w", level, err)
}

Prevention

When it happens

Trigger: Calling gzip.SetLevel(level) at init time with level < -1 (including HuffmanOnly -2) or level > 9. Common when a configurable env var or flag is parsed to an int and forwarded unvalidated.

Common situations: Reading compression level from a config/flag that defaulted to 0 (which is valid and means no compression) vs an out-of-range sentinel; passing a negative number to mean 'disabled'; copy-pasting a constant from another library.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/d76208fd1e6ec994. Report an issue: GitHub.