golang/go · critical
decompressor already registered
Error message
decompressor already registered
What it means
`zip.RegisterDecompressor(method, dcomp)` installs a custom decompressor for a given zip method ID; it panics if a decompressor for that method is already registered. The package's `init` pre-registers Store(0) and Deflate(8), so re-registering either panics. Registration is global (a `sync.Map` shared process-wide).
Source
Thrown at src/archive/zip/register.go:121
var (
compressors sync.Map // map[uint16]Compressor
decompressors sync.Map // map[uint16]Decompressor
)
func init() {
compressors.Store(Store, Compressor(func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil }))
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)
}View on GitHub (pinned to b6b368adc5)
Solutions
- Only register non-built-in methods once, early in main or a single package init.
- Avoid re-registering `zip.Store` (0) and `zip.Deflate` (8).
- Guard with a sentinel (e.g. a `sync.Once` or a package-level bool) if registration may be reached from multiple paths.
Example fix
// before
func init() {
zip.RegisterDecompressor(12, bzip2Reader) // panics if loaded twice
}
// after
var registerOnce sync.Once
func ensureBzip2() {
registerOnce.Do(func() { zip.RegisterDecompressor(12, bzip2Reader) })
} Defensive patterns
Strategy: validation
Validate before calling
var regDec sync.Once
regDec.Do(func() { zip.RegisterDecompressor(12, newBzip2Reader) }) Prevention
- Never re-register zip.Store or zip.Deflate.
- Centralize all codec registration in a single package imported once.
When it happens
Trigger: Calling `RegisterDecompressor(zip.Store, ...)` or `RegisterDecompressor(zip.Deflate, ...)` — both already registered at init; calling your custom registration twice in the same binary; a library and its test both registering the same method; an `init()` ordering issue causing a duplicate.
Common situations: A third-party zip codec library's `init` colliding with your own; tests that re-register on each run; a plugin/host both registering BZIP2/ZIP method 12.
Related errors
- compressor 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/4665655152340590.
Report an issue: GitHub.