gohugoio/hugo · error
failed to compile Redirect regexp
Error message
failed to compile Redirect regexp %q: %w
What it means
Emitted by Server.CompileConfig when a redirect's `fromRe` regexp fails to compile via Go's regexp package. This is the regex-based matcher (alternative to glob `from`), used when you need capture groups for substitution in `to`.
Solutions
- Test `fromRe` with Go regexp semantics (RE2). No backreferences/lookahead.
- Balance groups; escape metacharacters intended literally.
- Use named groups or positional groups referenced as $1 in `to`.
Example fix
# before (invalid RE2 lookahead) [[server.redirects]] fromRe = "^/old/(?=sub).*" to = "/new" # after [[server.redirects]] fromRe = "^/old/(.*)" to = "/new/$1"
Defensive patterns
Strategy: validation
Validate before calling
python3 - <<'PY'
import tomllib,re
cfg=tomllib.loads(open('hugo.toml').read())
for r in cfg.get('server',{}).get('redirects',[]):
fr=r.get('fromRe','')
if fr:
try: re.compile(fr)
except re.error as e: print(f"bad fromRe {fr!r}: {e}")
print("redirect regexps ok")
PY Prevention
- Use Go RE2 syntax for fromRe (no backreferences/lookahead).
- Reference capture groups as $1, $2 in `to`.
- Escape metacharacters intended literally.
When it happens
Trigger: A `[[server.redirects]]` with `fromRe` set to an invalid Go regexp: unbalanced parens, invalid escape, unsupported syntax.
Common situations: Using PCRE-only syntax unsupported by Go RE2 (e.g. backreferences, lookahead); copy-pasting a regex from another language.
Related errors
- failed to compile Redirect glob
- failed to compile Redirect header glob
- redirects must have either From or FromRe set
- --appendPort=false not supported when in multihost mode
- failed to compile cache buster
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/12f45b0e3a35dec2.
Report an issue: GitHub.
Appendix: source
Thrown at config/commonConfig.go:277
}
for _, r := range s.Redirects {
if r.From == "" && r.FromRe == "" {
return fmt.Errorf("redirects must have either From or FromRe set")
}
rd := redirect{
headers: make(map[string]glob.Glob),
}
if r.From != "" {
g, err := glob.Compile(r.From)
if err != nil {
return fmt.Errorf("failed to compile Redirect glob %q: %w", r.From, err)
}
rd.from = g
}
if r.FromRe != "" {
re, err := regexp.Compile(r.FromRe)
if err != nil {
return fmt.Errorf("failed to compile Redirect regexp %q: %w", r.FromRe, err)
}
rd.fromRe = re
}
for k, v := range r.FromHeaders {
g, err := glob.Compile(v)
if err != nil {
return fmt.Errorf("failed to compile Redirect header glob %q: %w", v, err)
}
rd.headers[k] = g
}
s.compiledRedirects = append(s.compiledRedirects, rd)
}
return nil
}
func (s *Server) MatchHeaders(pattern string) []types.KeyValueStr {
if s.compiledHeaders == nil {View on GitHub (pinned to 52c9bd7908)