caddyserver/caddy · error
encoding is duplicated in prefer
Error message
encoding %s is duplicated in prefer
What it means
Encode.Validate found the same encoding name listed more than once in the 'prefer' list. Duplicate preference entries are meaningless and likely a config mistake, so validation fails naming the duplicated encoding.
Solutions
- Remove duplicate entries from the prefer array
- If generating config, deduplicate the list before serializing
Example fix
// before "prefer": ["zstd", "gzip", "zstd"] // after "prefer": ["zstd", "gzip"]
Defensive patterns
Strategy: validation
Validate before calling
// dedupe before writing config
seen := map[string]bool{}
out := enc.Prefer[:0]
for _, p := range enc.Prefer {
if !seen[p] { seen[p] = true; out = append(out, p) }
} Prevention
- Deduplicate preference lists in config generators
- caddy validate catches this before reload
When it happens
Trigger: {"prefer": ["zstd", "zstd"]} — a repeated entry in the preference list.
Common situations: Config generated by concatenation or copy-paste producing duplicate entries; YAML anchors merging lists with overlap.
Related errors
- encoding not enabled
- quality too high; must be <=
- quality too low; must be >=
- unexpected compression level, use one of
- automation policy is the second policy that acts as…
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/9144064f75d58c6f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/caddyhttp/encode/encode.go:152
if _, ok := enc.writerPools[encName]; ok {
enc.Prefer = append(enc.Prefer, encName)
}
}
}
return nil
}
// Validate ensures that enc's configuration is valid.
func (enc *Encode) Validate() error {
check := make(map[string]bool)
for _, encName := range enc.Prefer {
if _, ok := enc.writerPools[encName]; !ok {
return fmt.Errorf("encoding %s not enabled", encName)
}
if _, ok := check[encName]; ok {
return fmt.Errorf("encoding %s is duplicated in prefer", encName)
}
check[encName] = true
}
return nil
}
func isEncodeAllowed(h http.Header) bool {
return !strings.Contains(h.Get("Cache-Control"), "no-transform")
}
func (enc *Encode) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
if isEncodeAllowed(r.Header) {
for _, encName := range AcceptedEncodings(r, enc.Prefer) {
if _, ok := enc.writerPools[encName]; !ok {
continue // encoding not offered
}
w = enc.openResponseWriter(encName, w, r.Method == http.MethodConnect)View on GitHub (pinned to 50e54ee279)