gohugoio/hugo · error

failed to compile Redirect header glob

Error message

failed to compile Redirect header glob %q: %w

What it means

Emitted by Server.CompileConfig while compiling a redirect's `fromHeaders` map. Each header value is compiled as a glob via gobwas/glob; headers gate whether a matched redirect actually fires. If any header value's glob is malformed, the error is wrapped with that value.

Solutions

  1. Use glob syntax for every `fromHeaders` value.
  2. Balance braces/brackets; test the value in a glob tester.
  3. Remove the header condition if not needed.

Example fix

# before
[[server.redirects]]
from = "/old/*"
fromHeaders = { Host = "{bad" }
to = "/new"

# after
[[server.redirects]]
from = "/old/*"
fromHeaders = { Host = "example.{com,org}" }
to = "/new"
Defensive patterns

Strategy: validation

Validate before calling

python3 - <<'PY'
import tomllib
cfg=tomllib.loads(open('hugo.toml').read())
for r in cfg.get('server',{}).get('redirects',[]):
    for hk,hv in (r.get('fromHeaders') or {}).items():
        assert hv.count('{')==hv.count('}') and hv.count('[')==hv.count(']'), f"unbalanced header glob {hv!r}"
print("redirect header globs ok")
PY

Prevention

When it happens

Trigger: A `[[server.redirects]]` with a `fromHeaders` entry like `{ Host = "{bad" }` whose glob is invalid.

Common situations: Using regexp syntax in a header glob field; malformed brace expansion in a Host matcher.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/75c02ac8169199b2. Report an issue: GitHub.

Appendix: source

Thrown at config/commonConfig.go:284

		}
		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 {
		return nil
	}

	var matches []types.KeyValueStr

	for i, g := range s.compiledHeaders {
		if g.Match(pattern) {

View on GitHub (pinned to 52c9bd7908)