caddyserver/caddy · error
module not registered: %s
Error message
module not registered: %s
What it means
caddy.GetModule(name) looks a module up by its full namespaced ID in the global registry; if no module with that exact ID was registered at init time, it returns this error. Registration happens only for packages compiled into the binary.
Source
Thrown at modules.go:169
panic("ModuleInfo.New must return a non-nil module instance")
}
modulesMu.Lock()
defer modulesMu.Unlock()
if _, ok := modules[string(mod.ID)]; ok {
panic(fmt.Sprintf("module already registered: %s", mod.ID))
}
modules[string(mod.ID)] = mod
}
// GetModule returns module information from its ID (full name).
func GetModule(name string) (ModuleInfo, error) {
modulesMu.RLock()
defer modulesMu.RUnlock()
m, ok := modules[name]
if !ok {
return ModuleInfo{}, fmt.Errorf("module not registered: %s", name)
}
return m, nil
}
// GetModuleName returns a module's name (the last label of its ID)
// from an instance of its value. If the value is not a module, an
// empty string will be returned.
func GetModuleName(instance any) string {
var name string
if mod, ok := instance.(Module); ok {
name = mod.CaddyModule().ID.Name()
}
return name
}
// GetModuleID returns a module's ID from an instance of its value.
// If the value is not a module, an empty string will be returned.
func GetModuleID(instance any) string {View on GitHub (pinned to 50e54ee279)
Solutions
- Use the full module ID including namespace: 'http.handlers.file_server', not 'file_server'.
- Run 'caddy list-modules' in the actual binary to see what is registered.
- For custom builds, import the package (blank import if needed) so its init() registers the module, or rebuild via xcaddy with the plugin.
- Check the module ID against the docs for your Caddy version — IDs occasionally change across majors.
Example fix
// before
info, err := caddy.GetModule("file_server")
// after
info, err := caddy.GetModule("http.handlers.file_server") Defensive patterns
Strategy: validation
Validate before calling
// check registration before use
if _, err := caddy.GetModule(fullModuleID); err != nil {
return fmt.Errorf("build is missing module %s — rebuild with xcaddy or fix the ID: %w", fullModuleID, err)
} Try / catch
info, err := caddy.GetModule(id)
if err != nil {
if strings.Contains(err.Error(), "module not registered") {
// fall back to a registered alternative or fail the run with a clear message
}
return err
} Prevention
- Use full namespaced IDs, never short names.
- Assert required modules exist at startup via caddy.GetModule guards.
- Keep 'caddy list-modules' output in version control next to the build recipe.
When it happens
Trigger: Calling caddy.GetModule with a misspelled or non-existent module ID; looking up a standard module in a custom build that does not import modules/standard; looking up a plugin module without having built with xcaddy.
Common situations: Custom minimal builds that omit standard imports; code or configs referencing a module renamed between Caddy versions; plugins looked up by short name instead of full ID (e.g. 'file_server' instead of 'http.handlers.file_server').
Related errors
- module name '%s': %v
- unknown module: %s
- module ID missing
- missing ModuleInfo.New
- ModuleInfo.New must return a non-nil module instance
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/4ecf8c1c29ff76a1.
Report an issue: GitHub.