caddyserver/caddy · error

compiling regexp for mapping %d: %v

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.

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)

Solutions

  1. Test the pattern with Go's regexp.Compile (or grep -P will NOT suffice — use a RE2 tester).
  2. Remove PCRE-only constructs: rewrite lookaheads as separate mappings or use alternation.
  3. Escape literal braces: a\{2\} not a{2}.
  4. 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

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


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/4823ef85830a1aa3. Report an issue: GitHub.