caddyserver/caddy · error
loading module '%s': %v
Error message
loading module '%s': %v
What it means
loadModuleInline extracts the module name from a JSON object using the expected inline key (module name embedded in the object, e.g. "handler": "reverse_proxy"), then loads it via LoadModuleByID with the scope prefixed. Any failure — bad inline key handling from getModuleNameInline, unknown module, decode/provision/validate errors — is wrapped as "loading module '%s': %v" naming the inline module name that was read.
Source
Thrown at context.go:486
// a map[string]any, where one of the object keys is moduleNameKey
// and the corresponding value is the module name (as a string) which can
// be found in the given scope. In other words, the module name is declared
// in-line with the module itself.
//
// This allows modules to be decoded into their concrete types and used when
// their names cannot be the unique key in a map, such as when there are
// multiple instances in the map or it appears in an array (where there are
// no custom keys). In other words, the key containing the module name is
// treated special/separate from all the other keys in the object.
func (ctx Context) loadModuleInline(moduleNameKey, moduleScope string, raw json.RawMessage) (any, error) {
moduleName, raw, err := getModuleNameInline(moduleNameKey, raw)
if err != nil {
return nil, err
}
val, err := ctx.LoadModuleByID(moduleScope+"."+moduleName, raw)
if err != nil {
return nil, fmt.Errorf("loading module '%s': %v", moduleName, err)
}
return val, nil
}
// App returns the configured app named name. If that app has
// not yet been loaded and provisioned, it will be immediately
// loaded and provisioned. If no app with that name is
// configured, a new empty one will be instantiated instead.
// (The app module must still be registered.) This must not be
// called during the Provision/Validate phase to reference a
// module's own host app (since the parent app module is still
// in the process of being provisioned, it is not yet ready).
//
// We return any type instead of the App type because it is NOT
// intended for the caller of this method to be the one to start
// or stop App modules. The caller is expected to assert to the
// concrete type.View on GitHub (pinned to 50e54ee279)
Solutions
- Confirm the inline module-name key is present and correct in the JSON object (commonly "handler" for handlers, "matcher" for matchers)
- Verify the module name value against `caddy list-modules` (the error shows the parsed name)
- Address the inner %v error, which carries the precise LoadModuleByID failure (unknown module / decoding / provision / validate)
- If adapting from Caddyfile, re-run `caddy adapt` to regenerate well-formed inline modules
Example fix
// before
{ "body": "hi" } // handler key missing
// after
{ "handler": "static_response", "body": "hi" } Defensive patterns
Strategy: validation
Validate before calling
// Ensure inline objects carry the module-name key before loading
func hasInlineKey(raw json.RawMessage, key string) bool {
var obj map[string]json.RawMessage
if err := json.Unmarshal(raw, &obj); err != nil { return false }
_, ok := obj[key]
return ok
} Type guard
func isInlineModule(raw json.RawMessage) bool {
var obj map[string]json.RawMessage
return json.Unmarshal(raw, &obj) == nil && len(obj) > 0
} Try / catch
if _, err := ctx.loadModuleInline(key, scope, raw); err != nil { return fmt.Errorf("inline module: %w", err) } // quotes the parsed module name Prevention
- Always include the inline module-name key in object-form modules
- Use `caddy adapt` output as the canonical shape reference
- Confirm module names exist via `caddy list-modules`
When it happens
Trigger: Calling ctx.loadModuleInline (internally from LoadModule on raw-message fields) where the object's inline key is missing (getModuleNameInline error), the name after scope-prefixing is not registered, or the module's config fails decoding/provisioning — each surfaces wrapped with the parsed module name.
Common situations: JSON routes missing the "handler" key; wrong inline key name for the module family; unregistered/misspelled module names in inline positions; nested module config errors reported one level down.
Related errors
- position %d: %v
- key %s: %v
- decoding module config: %s: %v
- decoding request body: %w, at offset %d
- decoding request body: %w
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/6e4134da465bbff3.
Report an issue: GitHub.