{"record":{"id":"558b3233d8a731e3","repo":"golang/go","slug":"gzip-invalid-compression-level-d","errorCode":null,"errorMessage":"gzip: invalid compression level: %d","messagePattern":"gzip: invalid compression level: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/compress/gzip/gzip.go","lineNumber":70,"sourceCode":"// exact written bytes.\nfunc NewWriter(w io.Writer) *Writer {\n\tz, _ := NewWriterLevel(w, DefaultCompression)\n\treturn z\n}\n\n// NewWriterLevel is like [NewWriter] but specifies the compression level instead\n// of assuming [DefaultCompression].\n//\n// The compression level can be [DefaultCompression], [NoCompression], [HuffmanOnly]\n// or any integer value between [BestSpeed] and [BestCompression] inclusive.\n// The error returned will be nil if the level is valid.\n//\n// Note that the exact bytes written to w are not covered by the Go 1\n// compatibility promise. Callers, including tests, should not depend on the\n// exact written bytes.\nfunc NewWriterLevel(w io.Writer, level int) (*Writer, error) {\n\tif level < HuffmanOnly || level > BestCompression {\n\t\treturn nil, fmt.Errorf(\"gzip: invalid compression level: %d\", level)\n\t}\n\tz := new(Writer)\n\tz.init(w, level)\n\treturn z, nil\n}\n\nfunc (z *Writer) init(w io.Writer, level int) {\n\tcompressor := z.compressor\n\tif compressor != nil {\n\t\tcompressor.Reset(w)\n\t}\n\t*z = Writer{\n\t\tHeader: Header{\n\t\t\tOS: 255, // unknown\n\t\t},\n\t\tw:          w,\n\t\tlevel:      level,\n\t\tcompressor: compressor,","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/compress/gzip/gzip.go#L52-L88","documentation":"`gzip.NewWriterLevel` validates that `level` is within `[HuffmanOnly(-2), BestCompression(9)]` before constructing the writer. Anything outside returns this error immediately — no writer is created. This is the public-API guard for gzip's compression level (it internally defers to flate).","triggerScenarios":"Calling `gzip.NewWriterLevel(w, level)` with level < -2 or > 9; reading a level from config that uses a 1..12 or 0..100 scale; passing `gzip.DefaultCompression` (which is -1 and valid) versus a custom sentinel that resolves to e.g. 100.","commonSituations":"A `compression` knob in a settings file exposed without bounds; wrapping gzip behind an interface where the caller passes an unrelated integer; copy-pasting a zlib-style level (same range but the user misremembers as 0..10).","solutions":["Clamp before constructing: `if level < gzip.HuffmanOnly { level = gzip.DefaultCompression } else if level > gzip.BestCompression { level = gzip.BestCompression }`.","Use named constants from the gzip package instead of raw integers.","If you only want the default, call `gzip.NewWriter(w)` (no level)."],"exampleFix":"// before\ngw, err := gzip.NewWriterLevel(out, 12)\n// after\ngw, err := gzip.NewWriterLevel(out, gzip.BestCompression)","handlingStrategy":"validation","validationCode":"if level < gzip.HuffmanOnly || level > gzip.BestCompression {\n    return nil, fmt.Errorf(\"gzip level %d out of range\", level)\n}","typeGuard":null,"tryCatchPattern":"gw, err := gzip.NewWriterLevel(out, level)\nif err != nil { level = gzip.DefaultCompression; gw, _ = gzip.NewWriterLevel(out, level) }","preventionTips":["If you don't need a specific level, use gzip.NewWriter (default).","Document the valid level range next to any config knob you expose."],"tags":["compress","gzip","argument-validation","configuration"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}