caddyserver/caddy · error

compiling regular expression %d: %v

Error message

compiling regular expression %d: %v

What it means

The rewrite handler compiles each path_regexp pattern with Go's regexp.Compile at provision time; this error wraps a compile failure and includes the 0-based index of the offending entry. Go's RE2 syntax differs from PCRE, so patterns valid in nginx or Perl (backreferences, lookaheads) fail here. The error is fatal at config load.

Source

Thrown at modules/caddyhttp/rewrite/rewrite.go:116

// CaddyModule returns the Caddy module information.
func (Rewrite) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "http.handlers.rewrite",
		New: func() caddy.Module { return new(Rewrite) },
	}
}

// Provision sets up rewr.
func (rewr *Rewrite) Provision(ctx caddy.Context) error {
	rewr.logger = ctx.Logger()

	for i, rep := range rewr.PathRegexp {
		if rep.Find == "" {
			return fmt.Errorf("path_regexp find cannot be empty")
		}
		re, err := regexp.Compile(rep.Find)
		if err != nil {
			return fmt.Errorf("compiling regular expression %d: %v", i, err)
		}
		rep.re = re
	}
	if rewr.Query != nil {
		for _, replacementOp := range rewr.Query.Replace {
			err := replacementOp.Provision(ctx)
			if err != nil {
				return fmt.Errorf("compiling regular expression %s in query rewrite replace operation: %v", replacementOp.SearchRegexp, err)
			}
		}
	}

	return nil
}

func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
	repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
	const message = "rewrote request"

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Read the wrapped regexp error — it names the exact syntax problem and position
  2. Replace PCRE-only constructs: drop lookaheads/backreferences, rewrite with capture groups used via {re.match.1} placeholders
  3. Double-check backslash escaping in JSON/Caddyfile ("\\d" in JSON for \d)
  4. Test the pattern standalone: echo 'pattern' in Go regexp tester or 'go run' a snippet with regexp.Compile

Example fix

// before
"path_regexp": [{ "find": "/old(/", "replace": "/new" }]

// after
"path_regexp": [{ "find": "/old(/", "replace": "/new" }]  // balanced: "/old(/" -> "/old(/" 
// concretely: "find": "/old/(.*)", "replace": "/new/{re.match.1}"
Defensive patterns

Strategy: validation

Validate before calling

for i, rep := range rewriteCfg.PathRegexp {
    if _, err := regexp.Compile(rep.Find); err != nil {
        return fmt.Errorf("path_regexp[%d] has invalid regex %q: %w", i, rep.Find, err)
    }
}

Prevention

When it happens

Trigger: A path_regexp 'find' containing invalid RE2 syntax: unbalanced parentheses like "(/old", bad escapes like "\d+" written as "\d+" in JSON without proper quoting, or PCRE-only constructs like "(?=foo)" or "(a)\1".

Common situations: Porting nginx rewrite rules (lookaheads/backreferences) to Caddy, JSON escaping mistakes where the regex loses its backslashes, or using { } quantifiers that clash with Caddy placeholder syntax without escaping.

Related errors


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