caddyserver/caddy · error
module %s is not a precompressor; is %T
Error message
module %s is not a precompressor; is %T
What it means
`caddy file-server --precompressed X` startup error: the module http.precompressed.X exists but its instance does not implement encode.Precompressed. The message reports the concrete Go type of the instance. This guards against a module squatting the precompressed namespace without the required interface.
Source
Thrown at modules/caddyhttp/fileserver/command.go:144
handler := caddytpl.Templates{FileRoot: root}
handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "templates", nil))
}
handler := FileServer{Root: root}
if len(precompressed) != 0 {
// logic mirrors modules/caddyhttp/fileserver/caddyfile.go case "precompressed"
var order []string
for _, compression := range precompressed {
modID := "http.precompressed." + compression
mod, err := caddy.GetModule(modID)
if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("getting module named '%s': %v", modID, err)
}
inst := mod.New()
precompress, ok := inst.(encode.Precompressed)
if !ok {
return caddy.ExitCodeFailedStartup, fmt.Errorf("module %s is not a precompressor; is %T", modID, inst)
}
if handler.PrecompressedRaw == nil {
handler.PrecompressedRaw = make(caddy.ModuleMap)
}
handler.PrecompressedRaw[compression] = caddyconfig.JSON(precompress, nil)
order = append(order, compression)
}
handler.PrecompressedOrder = order
}
if browse {
handler.Browse = &Browse{RevealSymlinks: revealSymlinks, FileLimit: fileLimit}
}
handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "file_server", nil))
route := caddyhttp.Route{HandlersRaw: handlers}
View on GitHub (pinned to 50e54ee279)
Solutions
- Check the reported type — if it's your plugin, implement encode.Precompressed properly
- Remove or update the offending plugin in the xcaddy build
- Use only well-maintained precompressor plugins
Example fix
// plugin must satisfy the interface var _ encode.Precompressed = (*MyPrecompress)(nil)
Defensive patterns
Strategy: type-guard
Type guard
// plugin compile-time interface guard var _ encode.Precompressed = (*MyPrecompress)(nil)
Prevention
- Only register modules under http.precompressed if they implement encode.Precompressed
- Keep plugins updated with the Caddy API version you build against
When it happens
Trigger: A third-party module registers itself under http.precompressed.<name> but its New() returns a type lacking the Precompressed interface (Encode()/AcceptEncoding()-style methods).
Common situations: Custom/xcaddy plugins misusing the http.precompressed namespace; version mismatches where the plugin targets an older Caddy API.
Related errors
- invalid precompressed flag: %v
- getting module named '%s': %v
- module %s is not precompressor
- filesystem not found
- source %T does not implement CertificateProvider (required f
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/2d4a1239739efaa8.
Report an issue: GitHub.