gohugoio/hugo · error

failed to compile Headers glob

Error message

failed to compile Headers glob %q: %w

What it means

Emitted by Server.CompileConfig while compiling each entry in server.Headers. Each header's `for` field is compiled with gobwas/glob (not regexp). If the glob pattern is malformed (unbalanced braces/brackets, invalid char-class), the compile fails and is wrapped with the offending `for` value.

Solutions

  1. Use glob syntax for `for` (supports *, ?, {a,b}, character classes).
  2. Balance any braces and brackets.
  3. Strip the rule to a simple `/*` and re-add complexity.

Example fix

# before
[[server.headers]]
for = "/*.{js,css"

# after
[[server.headers]]
for = "/*.{js,css}"
Defensive patterns

Strategy: validation

Validate before calling

python3 - <<'PY'
# Approximate glob sanity: balance braces/brackets
import tomllib
cfg=tomllib.loads(open('hugo.toml').read())
for h in cfg.get('server',{}).get('headers',[]):
    f=h['for']
    assert f.count('{')==f.count('}'), f"unbalanced braces in {f!r}"
    assert f.count('[')==f.count(']'), f"unbalanced brackets in {f!r}"
print("headers glob ok")
PY

Prevention

When it happens

Trigger: A `[[server.headers]]` block whose `for` glob is invalid, e.g. unbalanced `{` or a malformed character class.

Common situations: Writing a dev-server header rule and using regex syntax instead of glob; copy-paste leaving a dangling brace.

Related errors


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

Appendix: source

Thrown at config/commonConfig.go:256

}

func (r redirect) matchHeader(header http.Header) bool {
	for k, v := range r.headers {
		if !v.Match(header.Get(k)) {
			return false
		}
	}
	return true
}

func (s *Server) CompileConfig(logger loggers.Logger) error {
	if s.compiledHeaders != nil {
		return nil
	}
	for _, h := range s.Headers {
		g, err := glob.Compile(h.For)
		if err != nil {
			return fmt.Errorf("failed to compile Headers glob %q: %w", h.For, err)
		}
		s.compiledHeaders = append(s.compiledHeaders, g)
	}
	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 != "" {

View on GitHub (pinned to 52c9bd7908)