caddyserver/caddy · error · ErrNotConfigured
module not configured
Error message
module not configured
What it means
ErrNotConfigured is the exported sentinel error ("module not configured") that AppIfConfigured wraps when an app is absent from the configuration. Callers are expected to test for it with errors.Is to distinguish 'not configured' from genuine load failures. Seeing this bare text means a wrapped error chain bottomed out at this sentinel.
Source
Thrown at context.go:549
if ctx.cfg == nil {
return nil, fmt.Errorf("app module %s: %w", name, ErrNotConfigured)
}
// if the app failed to load before, return the cached error
if err, ok := ctx.cfg.failedApps[name]; ok {
return nil, fmt.Errorf("loading %s app module: %v", name, err)
}
if app, ok := ctx.cfg.apps[name]; ok {
return app, nil
}
appRaw := ctx.cfg.AppsRaw[name]
if appRaw == nil {
return nil, fmt.Errorf("app module %s: %w", name, ErrNotConfigured)
}
return ctx.App(name)
}
// ErrNotConfigured indicates a module is not configured.
var ErrNotConfigured = fmt.Errorf("module not configured")
// Storage returns the configured Caddy storage implementation.
func (ctx Context) Storage() certmagic.Storage {
return ctx.cfg.storage
}
// Logger returns a logger that is intended for use by the most
// recent module associated with the context. Callers should not
// pass in any arguments unless they want to associate with a
// different module; it panics if more than 1 value is passed in.
//
// Originally, this method's signature was `Logger(mod Module)`,
// requiring that an instance of a Caddy module be passed in.
// However, that is no longer necessary, as the closest module
// most recently associated with the context will be automatically
// assumed. To prevent a sudden breaking change, this method's
// signature has been changed to be variadic, but we may remove
// the parameter altogether in the future. Callers should notView on GitHub (pinned to 50e54ee279)
Solutions
- Use errors.Is(err, caddy.ErrNotConfigured) instead of string matching to detect absence
- Supply the app config if the app is required for your module to function
- Design submodules to operate with sensible defaults when the host app is not configured
Example fix
// before
if strings.Contains(err.Error(), "not configured") { ... }
// after
if errors.Is(err, caddy.ErrNotConfigured) { ... } Defensive patterns
Strategy: type-guard
Type guard
func isNotConfigured(err error) bool { return errors.Is(err, caddy.ErrNotConfigured) } Try / catch
if _, err := ctx.AppIfConfigured(name); err != nil {
switch {
case errors.Is(err, caddy.ErrNotConfigured):
// not configured — expected for optional apps
default:
return err // real load failure
}
} Prevention
- Never string-match error text; always errors.Is against caddy.ErrNotConfigured
- Document which apps your module treats as optional
- Handle the sentinel at the boundary and fall back to documented defaults
When it happens
Trigger: Any AppIfConfigured call for an app missing from cfg (nil cfg, or no entry in apps/AppsRaw) unwraps to this sentinel; code that prints err.Error() on the returned error shows 'app module <name>: module not configured'.
Common situations: Plugin code needing to know whether e.g. the tls or pki app was user-configured; Caddyfile-derived configs where omitting a global option means the app is absent; version migrations where an app moved from implicit to explicit configuration.
Related errors
- app module %s: %w
- %v; additionally, aborting app %s: %v
- %s app module: start: %v
- loading %s app module: %v
- WebSocket connections aren't allowed.
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/2e608e6af5e9a308.
Report an issue: GitHub.