gohugoio/hugo · error
failed to compile whitelist pattern %q: %w
Error message
failed to compile whitelist pattern %q: %w
What it means
Returned by config/security.NewWhitelist when one of the configured security whitelist patterns fails regexp.Compile. Hugo's security policy (security.exec.allow, security.funcs.getenv, security.http.urls, etc.) is expressed as Go RE2 regular expressions, and any pattern (after stripping the '!' negation prefix) that is not valid RE2 aborts whitelist construction so the security policy is never partially applied.
Source
Thrown at config/security/whitelist.go:91
acceptSome = true
patternsStrings = append(patternsStrings, ps)
}
}
if !acceptSome {
return Whitelist{acceptNone: true}, nil
}
var allow, deny []*regexp.Regexp
for _, p := range patternsStrings {
raw := p
negate := strings.HasPrefix(p, hglob.NegationPrefix)
if negate {
raw = p[len(hglob.NegationPrefix):]
}
re, err := regexp.Compile(raw)
if err != nil {
return Whitelist{}, fmt.Errorf("failed to compile whitelist pattern %q: %w", p, err)
}
if negate {
deny = append(deny, re)
} else {
allow = append(allow, re)
}
}
return Whitelist{allow: allow, deny: deny, patternsStrings: patternsStrings}, nil
}
// MustNewWhitelist creates a new Whitelist from zero or more patterns and panics on error.
func MustNewWhitelist(patterns ...string) Whitelist {
w, err := NewWhitelist(patterns...)
if err != nil {
panic(err)
}
return wView on GitHub ↗ (pinned to 8a468df065)
Solutions
- Fix the named pattern so it compiles as Go RE2 — test it with regexp.Compile or at regex101 (Golang flavor); RE2 has no lookarounds or backreferences.
- If you meant a glob like dart-sass*, write it as a regexp: '^dart-sass' or '^dart-sass.*$'.
- Keep the '!' only as a leading negation prefix; the rest of the string after '!' must itself be a valid regexp.
- Use the literal 'none' keyword if you want to deny everything instead of writing an empty/broken pattern.
Example fix
# before (hugo.toml)
[security.exec]
allow = ['^dart-sass(', 'pandoc(?=.exe)']
# after
[security.exec]
allow = ['^dart-sass', '^pandoc'] Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate whitelist patterns before building config
for _, p := range patterns {
if _, err := regexp.Compile(p); err != nil {
return fmt.Errorf("invalid whitelist pattern %q: %w", p, err)
}
} Try / catch
cfg, err := security.NewWhitelist(patterns...)
if err != nil {
// report the offending pattern verbatim to the user; do not fall back to allow-all
return err
} Prevention
- Compile every security.exec/http/funcs whitelist entry with regexp.Compile before shipping the config
- Remember Hugo whitelist entries are RE2 regexps, not globs — escape dots and avoid glob syntax like *.example.com
- Add a CI step that loads the site config (hugo config) to catch bad patterns early
- Prefer the special 'none' keyword over an empty or malformed pattern
When it happens
Trigger: Setting a value in the [security] section of hugo.toml (e.g. security.exec.allow = ['^dart-sass(']) that is not a valid Go regexp; unbalanced parens/brackets, invalid escapes like \d in single-quoted YAML contexts gone wrong, or RE2-unsupported syntax such as lookaheads (?=...) or backreferences \1. Also hits via HUGO_SECURITY_* environment overrides and via MustNewWhitelist in module code, which panics with this wrapped error.
Common situations: Developers paste shell glob patterns (dart-sass*) or PCRE with lookahead copied from other tools into security.exec.allow when whitelisting binaries like pandoc, asciidoctor or dart-sass-embedded; forgetting that Hugo expects anchored regexps, not globs; escaping errors introduced when editing TOML vs YAML config formats.
Related errors
- errConfigNotSet
- failed to compile cache buster %q: %w
- failed to compile Redirect regexp %q: %w
- failed to compile cache buster source %q: %w
- failed to compile cache buster target %q: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/7cd510f1b287aa4a.json.
Report an issue: GitHub ↗.