{"record":{"id":"1919797483775a34","repo":"caddyserver/caddy","slug":"setting-up-error-subroutes-v","errorCode":null,"errorMessage":"setting up error subroutes: %v","messagePattern":"setting up error subroutes: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/subroute.go","lineNumber":65,"sourceCode":"// CaddyModule returns the Caddy module information.\nfunc (Subroute) CaddyModule() caddy.ModuleInfo {\n\treturn caddy.ModuleInfo{\n\t\tID:  \"http.handlers.subroute\",\n\t\tNew: func() caddy.Module { return new(Subroute) },\n\t}\n}\n\n// Provision sets up subrouting.\nfunc (sr *Subroute) Provision(ctx caddy.Context) error {\n\tif sr.Routes != nil {\n\t\terr := sr.Routes.Provision(ctx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"setting up subroutes: %v\", err)\n\t\t}\n\t\tif sr.Errors != nil {\n\t\t\terr := sr.Errors.Routes.Provision(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"setting up error subroutes: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (sr *Subroute) ServeHTTP(w http.ResponseWriter, r *http.Request, next Handler) error {\n\tsubroute := sr.Routes.Compile(next)\n\terr := subroute.ServeHTTP(w, r)\n\tif err != nil && sr.Errors != nil {\n\t\tr = sr.Errors.WithError(r, err)\n\t\terrRoute := sr.Errors.Routes.Compile(next)\n\t\treturn errRoute.ServeHTTP(w, r)\n\t}\n\treturn err\n}\n\n// Interface guards","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/subroute.go#L47-L83","documentation":"Returned by Subroute.Provision when the error-handling routes (the 'errors' sub-route of a subroute) fail to provision. It is the error-chain counterpart of 'setting up subroutes' and only fires when sr.Routes provisioned fine but sr.Errors.Routes did not.","triggerScenarios":"A JSON subroute with an 'errors' object whose 'routes' contain an invalid matcher or handler module; e.g. an error route referencing a handler that rejects its configuration during Provision.","commonSituations":"Converting a Caddyfile with 'handle_errors' to JSON and mis-editing it, adding custom error pages whose handler module is misspelled or missing from the build, or nesting unsupported matchers inside error routes.","solutions":["Inspect the wrapped error text to find the failing module in the errors.routes array","Verify the handler/matcher IDs exist in `caddy list-modules`","Simplify: remove the errors block to confirm the rest loads, then re-add it step by step","Regenerate the JSON from a working Caddyfile using `caddy adapt` to get canonical structure"],"exampleFix":"# before (caddyfile intent, broken JSON)\n\"errors\": { \"routes\": [ { \"handle\": [{ \"handler\": \"templatess\" }] } ] }\n\n# after\n\"errors\": { \"routes\": [ { \"handle\": [{ \"handler\": \"templates\" }] } ] }","handlingStrategy":"validation","validationCode":"caddy validate --config Caddyfile  # exercises Provision/Validate incl. errors.routes","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep error routes (handle_errors) as simple as possible and validate after each edit","Generate error-route JSON via caddy adapt from Caddyfile rather than hand-writing","After upgrading Caddy or plugins, re-validate the full config"],"tags":["caddy","subroute","error-handling","provisioning"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}