caddyserver/caddy · error
compiling matcher regexp %s: %v
Error message
compiling matcher regexp %s: %v
What it means
MatchRegexp.Provision compiles the `pattern` of path_regexp / header_regexp / query_regexp matchers with regexp.Compile (RE2). An invalid pattern aborts provisioning with the pattern text and Go's compile error. The compiled regex is cached on the matcher; it is also what feeds {http.regexp.<name>.*} placeholders, so it must compile before serving.
Source
Thrown at modules/caddyhttp/matchers.go:1592
// The regular expression to evaluate, in RE2 syntax,
// which is the same general syntax used by Go, Perl,
// and Python. For details, see
// [Go's regexp package](https://golang.org/pkg/regexp/).
// Captures are accessible via placeholders. Unnamed
// capture groups are exposed as their numeric, 1-based
// index, while named capture groups are available by
// the capture group name.
Pattern string `json:"pattern"`
compiled *regexp.Regexp
}
// Provision compiles the regular expression.
func (mre *MatchRegexp) Provision(caddy.Context) error {
re, err := regexp.Compile(mre.Pattern)
if err != nil {
return fmt.Errorf("compiling matcher regexp %s: %v", mre.Pattern, err)
}
mre.compiled = re
return nil
}
// Validate ensures mre is set up correctly.
func (mre *MatchRegexp) Validate() error {
if mre.Name != "" && !wordRE.MatchString(mre.Name) {
return fmt.Errorf("invalid regexp name (must contain only word characters): %s", mre.Name)
}
return nil
}
// Match returns true if input matches the compiled regular
// expression in mre. It sets values on the replacer repl
// associated with capture groups, using the given scope
// (namespace).
func (mre *MatchRegexp) Match(input string, repl *caddy.Replacer) bool {View on GitHub (pinned to 50e54ee279)
Solutions
- Validate the pattern with Go's regexp package (RE2) — not with grep -P or an online PCRE tester.
- Replace lookarounds/backreferences with RE2-compatible constructs or multiple matchers.
- Escape literal { } as \{ \} so they are not read as quantifiers.
- Check escaping across config layers: JSON needs \\d to deliver \d to the regex compiler.
Example fix
// before (Caddyfile) @api path_regexp ^/v(?<ver>\d+)/users/(?=admin) // after @api path_regexp ^/v(?P<ver>\d+)/users/admin
Defensive patterns
Strategy: validation
Validate before calling
import "regexp"
func validMatcherPattern(p string) bool {
_, err := regexp.Compile(p)
return err == nil
} Prevention
- Validate all path_regexp/header_regexp patterns with Go's regexp.Compile in CI.
- Use RE2-compatible syntax; no lookbehind or backreferences.
- Escape literal braces; mind backslashes through JSON/shell.
When it happens
Trigger: @foo path_regexp [unclosed, `a{3,1}`, or PCRE-only syntax like (?<=x) lookbehind and backreferences \1; header_regexp blocks with patterns mangled by Caddyfile quoting.
Common situations: Porting nginx/Perl regex knowledge to Caddy; backslash escaping lost through JSON or shell layers (\d becoming d); patterns written for the regexp module family assuming PCRE.
Related errors
- compiling regexp for mapping %d: %v
- compiling regular expression %d: %v
- unsupported map key type in header match: %T
- unknown try policy %s
- replacement %d for header field '%s': %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/3fbce5eaa89fbf05.
Report an issue: GitHub.