caddyserver/caddy · error
loading matcher modules: %v
Error message
loading matcher modules: %v
What it means
Route.ProvisionMatchers calls ctx.LoadModule on the raw matcher sets; this wrapper fires when loading any matcher module fails. The root cause in the wrapped error is typically an unknown module ID (no matcher registered under that name) or a matcher whose own provisioning failed.
Source
Thrown at modules/caddyhttp/routes.go:147
// Provision sets up both the matchers and handlers in the route.
func (r *Route) Provision(ctx caddy.Context, metrics *Metrics) error {
err := r.ProvisionMatchers(ctx)
if err != nil {
return err
}
return r.ProvisionHandlers(ctx, metrics)
}
// ProvisionMatchers sets up all the matchers by loading the
// matcher modules. Only call this method directly if you need
// to set up matchers and handlers separately without having
// to provision a second time; otherwise use Provision instead.
func (r *Route) ProvisionMatchers(ctx caddy.Context) error {
// matchers
matchersIface, err := ctx.LoadModule(r, "MatcherSetsRaw")
if err != nil {
return fmt.Errorf("loading matcher modules: %v", err)
}
err = r.MatcherSets.FromInterface(matchersIface)
if err != nil {
return err
}
return nil
}
// ProvisionHandlers sets up all the handlers by loading the
// handler modules. Only call this method directly if you need
// to set up matchers and handlers separately without having
// to provision a second time; otherwise use Provision instead.
func (r *Route) ProvisionHandlers(ctx caddy.Context, metrics *Metrics) error {
handlersIface, err := ctx.LoadModule(r, "HandlersRaw")
if err != nil {
return fmt.Errorf("loading handler modules: %v", err)
}
for _, handler := range handlersIface.([]any) {View on GitHub (pinned to 50e54ee279)
Solutions
- Read the wrapped error — it names the module that failed to load
- Verify the matcher exists in this build: run 'caddy list-modules' and compare IDs
- Fix typos in the matcher name or field types in the match block
- If a plugin matcher is required, build Caddy with xcaddy including that plugin
Example fix
// before
"match": [{ "path_prefx": "/api" }]
// after
"match": [{ "path": "/api*" }] Defensive patterns
Strategy: validation
Validate before calling
modules := caddy.Modules() // library users
known := map[string]bool{}
for _, m := range modules { known[m.ID] = true }
for _, set := range route.MatcherSetsRaw {
for name := range set {
if !known["http.matchers."+name] {
return fmt.Errorf("unknown matcher %q", name)
}
}
}
// CLI: caddy list-modules | grep http.matchers Prevention
- Prefer Caddyfile syntax adapted via 'caddy adapt' to avoid hand-written module IDs
- Pin plugin versions in your xcaddy build and validate configs against that exact binary
- Run 'caddy list-modules' after rebuilds to diff available modules
When it happens
Trigger: JSON route with "match" referencing a nonexistent or misspelled matcher name (e.g. "path_prefx"), a matcher field with a wrong type, or a custom build missing a plugin module that the config expects.
Common situations: Custom JSON configs, configs written for a plugin not compiled into the binary, version skew between config and Caddy build, or typos in matcher names.
Related errors
- loading handler modules: %v
- route %d: %v
- server %s: setting up route matchers: %v
- invoke: route '%s' not found
- loading certificate loader modules: %s
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/ca1496787fd94ce7.
Report an issue: GitHub.