{"id":"12f45b0e3a35dec2","repo":"gohugoio/hugo","slug":"failed-to-compile-redirect-regexp-q-w","errorCode":null,"errorMessage":"failed to compile Redirect regexp %q: %w","messagePattern":"failed to compile Redirect regexp %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/commonConfig.go","lineNumber":277,"sourceCode":"\t}\n\tfor _, r := range s.Redirects {\n\t\tif r.From == \"\" && r.FromRe == \"\" {\n\t\t\treturn fmt.Errorf(\"redirects must have either From or FromRe set\")\n\t\t}\n\t\trd := redirect{\n\t\t\theaders: make(map[string]glob.Glob),\n\t\t}\n\t\tif r.From != \"\" {\n\t\t\tg, err := glob.Compile(r.From)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect glob %q: %w\", r.From, err)\n\t\t\t}\n\t\t\trd.from = g\n\t\t}\n\t\tif r.FromRe != \"\" {\n\t\t\tre, err := regexp.Compile(r.FromRe)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect regexp %q: %w\", r.FromRe, err)\n\t\t\t}\n\t\t\trd.fromRe = re\n\t\t}\n\t\tfor k, v := range r.FromHeaders {\n\t\t\tg, err := glob.Compile(v)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile Redirect header glob %q: %w\", v, err)\n\t\t\t}\n\t\t\trd.headers[k] = g\n\t\t}\n\t\ts.compiledRedirects = append(s.compiledRedirects, rd)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) MatchHeaders(pattern string) []types.KeyValueStr {\n\tif s.compiledHeaders == nil {","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/config/commonConfig.go#L259-L295","documentation":"Raised by Server.CompileConfig when the `fromRe` field of a `[[server.redirects]]` entry fails regexp.Compile. `fromRe` is a Go RE2 regular expression matched against request paths (supporting capture-group substitution in `to`), and an invalid pattern aborts config loading.","triggerScenarios":"A `[[server.redirects]]` entry with `fromRe` containing invalid RE2 syntax — e.g. `fromRe = \"^/blog/(\\\\d+\"` (unclosed group), PCRE lookarounds like `(?<!x)` / `(?=x)`, or backreferences `\\\\1`, none of which Go's regexp package supports.","commonSituations":"Porting nginx/Apache rewrite regexps that use lookahead or backreferences; forgetting to double-escape backslashes in TOML basic strings; putting glob syntax like `**` in `fromRe` where it means something different in a regexp.","solutions":["Fix the regexp quoted in the error to valid Go RE2 syntax; remove lookarounds and backreferences.","In TOML, use single-quoted literal strings (`fromRe = '^/post/(\\d+)$'`) to avoid backslash-escaping mistakes.","If you only need wildcard matching, use the `from` glob field instead of `fromRe`."],"exampleFix":"# before (hugo.toml)\n[[server.redirects]]\nfromRe = \"^/post/(\\\\d+\"\nto = \"/blog/$1\"\n\n# after\n[[server.redirects]]\nfromRe = '^/post/(\\d+)$'\nto = \"/blog/$1\"","handlingStrategy":"validation","validationCode":"if r.FromRe != \"\" {\n    if _, err := regexp.Compile(r.FromRe); err != nil {\n        return fmt.Errorf(\"redirect 'fromRe' %q invalid: %w\", r.FromRe, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := cfg.Server.CompileConfig(logger); err != nil {\n    // \"failed to compile Redirect regexp\" — validate the fromRe with Go's RE2 syntax\n    return err\n}","preventionTips":["`fromRe` uses Go RE2: no backreferences or lookaround — patterns ported from PCRE/Nginx often fail here","Prefer raw TOML strings ('...') so backslashes aren't double-escaped","Test the pattern with `regexp.MustCompile` in a Go playground or regex101 set to Golang"],"tags":["hugo","config","server","redirects","regexp"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}