golang/go · critical
compressor already registered
Error message
compressor already registered
What it means
`zip.RegisterCompressor(method, comp)` is the encoding-side twin of RegisterDecompressor. It panics if a compressor for `method` is already in the global `compressors` map (Store and Deflate are pre-registered by `init`). Same global-state/once-only contract.
Source
Thrown at src/archive/zip/register.go:129
compressors.Store(Deflate, Compressor(func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil }))
decompressors.Store(Store, Decompressor(io.NopCloser))
decompressors.Store(Deflate, Decompressor(newFlateReader))
}
// RegisterDecompressor allows custom decompressors for a specified method ID.
// The common methods [Store] and [Deflate] are built in.
func RegisterDecompressor(method uint16, dcomp Decompressor) {
if _, dup := decompressors.LoadOrStore(method, dcomp); dup {
panic("decompressor already registered")
}
}
// RegisterCompressor registers custom compressors for a specified method ID.
// The common methods [Store] and [Deflate] are built in.
func RegisterCompressor(method uint16, comp Compressor) {
if _, dup := compressors.LoadOrStore(method, comp); dup {
panic("compressor already registered")
}
}
func compressor(method uint16) Compressor {
ci, ok := compressors.Load(method)
if !ok {
return nil
}
return ci.(Compressor)
}
func decompressor(method uint16) Decompressor {
di, ok := decompressors.Load(method)
if !ok {
return nil
}
return di.(Decompressor)
}View on GitHub (pinned to b6b368adc5)
Solutions
- Register each method exactly once; use `sync.Once` or a package-level flag.
- Do not override `zip.Store`/`zip.Deflate` — they are wired by the package's own init.
- Consolidate codec registration into a single package imported by everyone who needs it.
Example fix
// before
func init() {
zip.RegisterCompressor(12, bzip2Writer) // panics on duplicate import
}
// after
var bzip2Reg sync.Once
func RegisterBzip2() {
bzip2Reg.Do(func() { zip.RegisterCompressor(12, bzip2Writer) })
} Defensive patterns
Strategy: validation
Validate before calling
var regComp sync.Once
regComp.Do(func() { zip.RegisterCompressor(12, newBzip2Writer) }) Prevention
- Register each custom method exactly once at startup.
- Use sync.Once to make registration idempotent across import paths.
When it happens
Trigger: Registering a compressor for `zip.Store` or `zip.Deflate`; registering a custom method (e.g. 12) twice; library + program both registering the same method; re-running registration inside a test loop without a guard.
Common situations: Two codecs packages registered via blank-import in the same binary; an `init()` in a vendored fork duplicating the upstream init; tests that re-init the codec map.
Related errors
- decompressor already registered
- zip: SetOffset called after data was written
- invalid file name: %v
- missing top-level directory prefix
- zip file contains more than one top-level directory
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/510286b8996fc90f.
Report an issue: GitHub.