caddyserver/caddy · error
module name '%s': %v
Error message
module name '%s': %v
What it means
loadModuleMap handles fields typed caddy.ModuleMap (map[string]json.RawMessage) where the MAP KEY is the module name (namespace already implied by the field's caddy tag). It calls ctx.LoadModuleByID(namespace+"."+key, value) per entry; any failure is wrapped as "module name '%s': %v" naming the map key. The inner error is usually 'unknown module', a decode failure, or a provision/validate failure.
Source
Thrown at context.go:347
}
return mods, nil
}
// loadModuleMap loads modules from a ModuleMap, i.e. map[string]any, where the key is the
// module name. With a module map, module names do not need to be defined inline with their values.
func (ctx Context) loadModuleMap(namespace string, val reflect.Value) (map[string]any, error) {
all := make(map[string]any)
iter := val.MapRange()
for iter.Next() {
k := iter.Key().Interface().(string)
v := iter.Value().Interface().(json.RawMessage)
moduleName := namespace + "." + k
if namespace == "" {
moduleName = k
}
val, err := ctx.LoadModuleByID(moduleName, v)
if err != nil {
return nil, fmt.Errorf("module name '%s': %v", k, err)
}
all[k] = val
}
return all, nil
}
// LoadModuleByID decodes rawMsg into a new instance of mod and
// returns the value. If mod.New is nil, an error is returned.
// If the module implements Validator or Provisioner interfaces,
// those methods are invoked to ensure the module is fully
// configured and valid before being used.
//
// This is a lower-level method and will usually not be called
// directly by most modules. However, this method is useful when
// dynamically loading/unloading modules in their own context,
// like from embedded scripts, etc.
func (ctx Context) LoadModuleByID(id string, rawMsg json.RawMessage) (any, error) {
modulesMu.RLock()View on GitHub (pinned to 50e54ee279)
Solutions
- Check the module name given in quotes against `caddy list-modules --packages` output for the expected namespace
- If the module comes from a plugin, rebuild with `xcaddy build --with <plugin@version>` or use a Caddy build that includes it
- Fix the JSON body of that entry if the inner error mentions decoding or provisioning
- Align config and binary versions: configs adapted by/for newer Caddy versions may reference renamed modules
Example fix
// before
"dns_challenge": { "cloudfare": {} } // typo in module name key
// after
"dns_challenge": { "cloudflare": { "api_token": "{env.CF_TOKEN}" } } Defensive patterns
Strategy: validation
Validate before calling
// Verify each ModuleMap key resolves to a registered module before load
mods := caddy.GetModules("dns") // or the relevant namespace
for name := range moduleMap {
if _, ok := mods[name]; !ok {
return fmt.Errorf("module name '%s' not registered in namespace", name)
}
} Type guard
func moduleRegistered(id string) bool {
for _, m := range caddy.Modules() { if m == id { return true } }
return false
} Try / catch
if _, err := ctx.LoadModule(field, raw); err != nil { return fmt.Errorf("%s: %w", field, err) } // 'module name K:' names the key Prevention
- Cross-check ModuleMap keys against `caddy list-modules` output
- Build custom binaries with xcaddy including all plugins referenced by config
- Keep config and binary versions in lockstep
When it happens
Trigger: A struct field of type caddy.ModuleMap tagged caddy:"module=namespace"; during LoadModule, an entry's key resolves to namespace.key which is not registered, or its JSON value fails StrictUnmarshalJSON/Provision/Validate, producing fmt.Errorf("module name '%s': %v", k, err).
Common situations: Using a DNS provider module (e.g. acme_dns) whose plugin is not compiled into the binary; misspelling the module name as the map key; a config written for a newer Caddy version using a module name that does not exist in the installed one.
Related errors
- position %d: %v
- key %s: %v
- unknown module: %s
- decoding module config: %s: %v
- %s: invalid configuration: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/395caedba6982da3.
Report an issue: GitHub.