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 not

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Use errors.Is(err, caddy.ErrNotConfigured) instead of string matching to detect absence
  2. Supply the app config if the app is required for your module to function
  3. 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

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


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