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

  1. Confirm the inline module-name key is present and correct in the JSON object (commonly "handler" for handlers, "matcher" for matchers)
  2. Verify the module name value against `caddy list-modules` (the error shows the parsed name)
  3. Address the inner %v error, which carries the precise LoadModuleByID failure (unknown module / decoding / provision / validate)
  4. 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

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


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/6e4134da465bbff3. Report an issue: GitHub.