{"record":{"id":"119f155b4fe7beea","repo":"caddyserver/caddy","slug":"compiling-regular-expression-s-in-query-rewrite-r","errorCode":null,"errorMessage":"compiling regular expression %s in query rewrite replace operation: %v","messagePattern":"compiling regular expression (.+?) in query rewrite replace operation: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/rewrite/rewrite.go","lineNumber":124,"sourceCode":"// Provision sets up rewr.\nfunc (rewr *Rewrite) Provision(ctx caddy.Context) error {\n\trewr.logger = ctx.Logger()\n\n\tfor i, rep := range rewr.PathRegexp {\n\t\tif rep.Find == \"\" {\n\t\t\treturn fmt.Errorf(\"path_regexp find cannot be empty\")\n\t\t}\n\t\tre, err := regexp.Compile(rep.Find)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"compiling regular expression %d: %v\", i, err)\n\t\t}\n\t\trep.re = re\n\t}\n\tif rewr.Query != nil {\n\t\tfor _, replacementOp := range rewr.Query.Replace {\n\t\t\terr := replacementOp.Provision(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"compiling regular expression %s in query rewrite replace operation: %v\", replacementOp.SearchRegexp, err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {\n\trepl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)\n\tconst message = \"rewrote request\"\n\n\tc := rewr.logger.Check(zap.DebugLevel, message)\n\tif c == nil {\n\t\trewr.Rewrite(r, repl)\n\t\treturn next.ServeHTTP(w, r)\n\t}\n\n\tchanged := rewr.Rewrite(r, repl)","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/rewrite/rewrite.go#L106-L142","documentation":"Wrapper error produced while provisioning the query-rewrite section of the rewrite handler. It surfaces when any query replace operation's Provision fails; the %s shows the operation's SearchRegexp so you can identify which regex is broken. The underlying cause is almost always the nested 'replacement for query field' regexp compile error.","triggerScenarios":"Config with rewrite.query.replace[] where search_regexp is set to an invalid RE2 pattern, e.g. \"[\" or \"(?i\" (unterminated).","commonSituations":"Adding query-parameter rewriting with copy-pasted regexes from other tools, or JSON escaping issues that corrupt the pattern.","solutions":["Note the search_regexp printed in the message and validate it with Go's RE2 syntax","Fix or remove the invalid search_regexp for that query key","Escape backslashes correctly in JSON","Run 'caddy validate' after editing"],"exampleFix":"// before\n\"query\": { \"replace\": [{ \"key\": \"q\", \"search_regexp\": \"[\", \"replace\": \"x\" }] }\n\n// after\n\"query\": { \"replace\": [{ \"key\": \"q\", \"search_regexp\": \"\\\\[\\\\d+\\\\]\", \"replace\": \"x\" }] }","handlingStrategy":"validation","validationCode":"for _, op := range rewriteCfg.Query.Replace {\n    if op.SearchRegexp != \"\" {\n        if _, err := regexp.Compile(op.SearchRegexp); err != nil {\n            return fmt.Errorf(\"query replace for %q has invalid regex: %w\", op.Key, err)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep query rewrite regexes trivial (anchors + character classes)","Prefer search_replace literal matching when a regex is not required","Validate configs in CI with 'caddy validate'"],"tags":["caddy","regex","query-string","rewrite","config"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}