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

  1. Register each method exactly once; use `sync.Once` or a package-level flag.
  2. Do not override `zip.Store`/`zip.Deflate` — they are wired by the package's own init.
  3. 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

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


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/510286b8996fc90f. Report an issue: GitHub.