{"record":{"id":"ca1496787fd94ce7","repo":"caddyserver/caddy","slug":"loading-matcher-modules-v","errorCode":null,"errorMessage":"loading matcher modules: %v","messagePattern":"loading matcher modules: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/routes.go","lineNumber":147,"sourceCode":"\n// Provision sets up both the matchers and handlers in the route.\nfunc (r *Route) Provision(ctx caddy.Context, metrics *Metrics) error {\n\terr := r.ProvisionMatchers(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn r.ProvisionHandlers(ctx, metrics)\n}\n\n// ProvisionMatchers sets up all the matchers by loading the\n// matcher modules. Only call this method directly if you need\n// to set up matchers and handlers separately without having\n// to provision a second time; otherwise use Provision instead.\nfunc (r *Route) ProvisionMatchers(ctx caddy.Context) error {\n\t// matchers\n\tmatchersIface, err := ctx.LoadModule(r, \"MatcherSetsRaw\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"loading matcher modules: %v\", err)\n\t}\n\terr = r.MatcherSets.FromInterface(matchersIface)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// ProvisionHandlers sets up all the handlers by loading the\n// handler modules. Only call this method directly if you need\n// to set up matchers and handlers separately without having\n// to provision a second time; otherwise use Provision instead.\nfunc (r *Route) ProvisionHandlers(ctx caddy.Context, metrics *Metrics) error {\n\thandlersIface, err := ctx.LoadModule(r, \"HandlersRaw\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"loading handler modules: %v\", err)\n\t}\n\tfor _, handler := range handlersIface.([]any) {","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/routes.go#L129-L165","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n\"match\": [{ \"path_prefx\": \"/api\" }]\n\n// after\n\"match\": [{ \"path\": \"/api*\" }]","handlingStrategy":"validation","validationCode":"modules := caddy.Modules() // library users\nknown := map[string]bool{}\nfor _, m := range modules { known[m.ID] = true }\nfor _, set := range route.MatcherSetsRaw {\n    for name := range set {\n        if !known[\"http.matchers.\"+name] {\n            return fmt.Errorf(\"unknown matcher %q\", name)\n        }\n    }\n}\n// CLI: caddy list-modules | grep http.matchers","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["caddy","config","matchers","module-loading","routing"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}