grpc/grpc-java · error · HeaderMutationRulesParseException

Invalid regex pattern for :

Error message

Invalid regex pattern for : 

What it means

The HeaderMutationRulesParser compiles regex fields from xDS HeaderMutation rules into Java Patterns. When a regex fails to compile (PatternSyntaxException), it wraps the failure in HeaderMutationRulesParseException with the field name and the underlying regex error. This fails fast on malformed xDS configuration.

Solutions

  1. Fix the regex so it compiles as a Java Pattern — use the message from e.getMessage() to locate the syntax error
  2. Test the regex with Pattern.compile() locally before embedding in config
  3. Escape metacharacters correctly (double backslashes in YAML/JSON strings)
  4. Rewrite RE2/PCRE-specific constructs into Java-compatible equivalents

Example fix

// before
parseRegex("[a-z+", "allowed_regular_expressions"); // unclosed class
// after
parseRegex("[a-z]+", "allowed_regular_expressions");
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  java.util.regex.Pattern.compile(regex);
} catch (PatternSyntaxException e) {
  throw new ConfigException("Invalid regex in rules: " + e.getMessage());
}

Try / catch

try {
  HeaderMutationRules.parse(rules);
} catch (HeaderMutationRulesParseException e) {
  log.error("Bad regex in field {}: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Parsing xDS HeaderMutation rules whose regex field (e.g., allowed_regular_expressions) contains an invalid Java-flavored regex, such as unbalanced brackets, bad escapes, or PCRE-only syntax.

Common situations: Configs authored for Envoy (RE2 syntax) containing constructs Java regex rejects (e.g., possessive quantifiers, named-group syntax differences, stray backslashes in YAML).

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/6e94c82ef9ef21f9. Report an issue: GitHub.

Appendix: source

Thrown at xds/src/main/java/io/grpc/xds/internal/headermutations/HeaderMutationRulesParser.java:51

    builder.disallowAll(proto.getDisallowAll().getValue());
    builder.disallowIsError(proto.getDisallowIsError().getValue());
    if (proto.hasAllowExpression()) {
      builder.allowExpression(
          parseRegex(proto.getAllowExpression().getRegex(), "allow_expression"));
    }
    if (proto.hasDisallowExpression()) {
      builder.disallowExpression(
          parseRegex(proto.getDisallowExpression().getRegex(), "disallow_expression"));
    }
    return builder.build();
  }

  private static Pattern parseRegex(String regex, String fieldName)
      throws HeaderMutationRulesParseException {
    try {
      return Pattern.compile(regex);
    } catch (PatternSyntaxException e) {
      throw new HeaderMutationRulesParseException(
          "Invalid regex pattern for " + fieldName + ": " + e.getMessage(), e);
    }
  }
}

View on GitHub (pinned to 64daddc1f3)