coredns/coredns · error

the rewrite regex pattern (%s) uses more subexpressions than

Error message

the rewrite regex pattern (%s) uses more subexpressions than its corresponding matching regex pattern (%s)

What it means

The replacement string may only reference as many subexpressions ({1}, {2}, ...) as the FROM pattern actually captures (regexp.NumSubexp). If getSubExprUsage(rewriteTo) exceeds that count, plugin setup fails because the rewrite could not fill the referenced groups.

Source

Thrown at plugin/rewrite/name.go:458

	for i := range 101 {
		if strings.Contains(s, "{"+strconv.Itoa(i)+"}") {
			subExprUsage++
		}
	}
	return subExprUsage
}

// isValidRegexPattern returns a regular expression for pattern matching or errors, if any.
func isValidRegexPattern(rewriteFrom, rewriteTo string) (*regexp.Regexp, error) {
	if len(rewriteFrom) > maxRegexpLen {
		return nil, fmt.Errorf("regex pattern too long: %d > %d", len(rewriteFrom), maxRegexpLen)
	}
	rewriteFromPattern, err := regexp.Compile(rewriteFrom)
	if err != nil {
		return nil, fmt.Errorf("invalid regex matching pattern: %s", rewriteFrom)
	}
	if getSubExprUsage(rewriteTo) > rewriteFromPattern.NumSubexp() {
		return nil, fmt.Errorf("the rewrite regex pattern (%s) uses more subexpressions than its corresponding matching regex pattern (%s)", rewriteTo, rewriteFrom)
	}
	return rewriteFromPattern, nil
}

View on GitHub (pinned to 558c9757a9)

Solutions

  1. Add the missing capture group(s) to the FROM pattern (wrap parts in parentheses)
  2. Or lower the {N} references in the replacement to match existing groups
  3. Recount capture groups carefully — non-capturing groups (?:...) do not count

Example fix

# before
rewrite stop name regex (.*)\.a\.com {2}.b.com
# after
rewrite stop name regex (.*)\.a\.com {1}.b.com
Defensive patterns

Strategy: validation

Validate before calling

func subexprCountOK(from, to string) bool {
	re, err := regexp.Compile(from)
	if err != nil { return false }
	return subExprUsage(to) <= re.NumSubexp()
}

Prevention

When it happens

Trigger: `rewrite stop name regex \.a\.com$ \.b\.com answer name \.a\.com$ {2}.c.com` — the TO side references {2} but the FROM pattern has fewer than 2 capture groups.

Common situations: Editing the FROM pattern to remove a capture group while the replacement still references it; copying replacement strings between rules with different patterns.

Related errors


AI-assisted analysis of coredns/coredns@558c9757a9 (2026-09-06). Data as JSON: /api/errors/89a6421ba8a838b1. Report an issue: GitHub.