caddyserver/caddy · error
compiling regexp for mapping
Error message
compiling regexp for mapping %d: %v
What it means
During Provision the map handler compiles each mapping's `input_regexp` with regexp.Compile. If any mapping's regular expression is invalid per Go's RE2 syntax, provisioning aborts with this error naming the mapping index and the underlying compile error.
Solutions
- Test the pattern with Go's regexp.Compile (or grep -P will NOT suffice — use a RE2 tester).
- Remove PCRE-only constructs: rewrite lookaheads as separate mappings or use alternation.
- Escape literal braces: a\{2\} not a{2}.
- Double-check backslash escaping through your config layer (JSON needs \\d for \d).
Example fix
// before
map {path} {http.vars.x} {
regexp ^/foo(?=bar) foo
}
// after
map {path} {http.vars.x} {
regexp ^/foo(bar) foo
} Defensive patterns
Strategy: validation
Validate before calling
import "regexp"
func validRegexps(patterns []string) bool {
for _, p := range patterns {
if _, err := regexp.Compile(p); err != nil {
return false
}
}
return true
} Prevention
- Test patterns with Go's regexp (RE2), not PCRE testers.
- Avoid lookarounds and backreferences.
- Watch backslash escaping through JSON/shell layers.
When it happens
Trigger: input_regexp values like "[unclosed", "a{3,1}" (quantifier range reversed), "(?P<name" (incomplete group), or PCRE-only constructs such as lookaheads "foo(?=bar)" that RE2 does not support.
Common situations: Porting regexes from PCRE/Perl/nginx (lookbehind, backreferences \1, \K) into Caddy; unescaped braces intended as literals while also using placeholders; shell/JSON escaping mangling backslashes so \d becomes d.
Related errors
- compiling matcher regexp
- compiling regular expression
- compiling regular expression
- destinations != defaults
- destination must be a placeholder and only a placeholder
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/4823ef85830a1aa3.
Report an issue: GitHub.
Appendix: source
Thrown at modules/caddyhttp/map/map.go:80
}
// Provision sets up h.
func (h *Handler) Provision(_ caddy.Context) error {
for j, dest := range h.Destinations {
if strings.Count(dest, "{") != 1 || !strings.HasPrefix(dest, "{") {
return fmt.Errorf("destination must be a placeholder and only a placeholder")
}
h.Destinations[j] = strings.Trim(dest, "{}")
}
for i, m := range h.Mappings {
if m.InputRegexp == "" {
continue
}
var err error
h.Mappings[i].re, err = regexp.Compile(m.InputRegexp)
if err != nil {
return fmt.Errorf("compiling regexp for mapping %d: %v", i, err)
}
}
// TODO: improve efficiency even further by using an actual map type
// for the non-regexp mappings, OR sort them and do a binary search
return nil
}
// Validate ensures that h is configured properly.
func (h *Handler) Validate() error {
nDest, nDef := len(h.Destinations), len(h.Defaults)
if nDef > 0 && nDef != nDest {
return fmt.Errorf("%d destinations != %d defaults", nDest, nDef)
}
seen := make(map[string]int)
for i, m := range h.Mappings {View on GitHub (pinned to 50e54ee279)