{"record":{"id":"16c49fdb5156fc22","repo":"grpc/grpc-java","slug":"headermatcher-contains-malformed-safe-regex-pat","errorCode":null,"errorMessage":"HeaderMatcher [] contains malformed safe regex pattern: ","messagePattern":"HeaderMatcher \\[\\] contains malformed safe regex pattern: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/MatcherParser.java","lineNumber":51,"sourceCode":"  }\n\n  /** Translates envoy proto HeaderMatcher to internal HeaderMatcher.*/\n  public static Matchers.HeaderMatcher parseHeaderMatcher(\n          io.envoyproxy.envoy.config.route.v3.HeaderMatcher proto) {\n    switch (proto.getHeaderMatchSpecifierCase()) {\n      case EXACT_MATCH:\n        @SuppressWarnings(\"deprecation\") // gRFC A63: support indefinitely\n        String exactMatch = proto.getExactMatch();\n        return Matchers.HeaderMatcher.forExactValue(\n                        proto.getName(), exactMatch, proto.getInvertMatch());\n      case SAFE_REGEX_MATCH:\n        @SuppressWarnings(\"deprecation\") // gRFC A63: support indefinitely\n        String rawPattern = proto.getSafeRegexMatch().getRegex();\n        Pattern safeRegExMatch;\n        try {\n          safeRegExMatch = Pattern.compile(rawPattern);\n        } catch (PatternSyntaxException e) {\n          throw new IllegalArgumentException(\n                \"HeaderMatcher [\" + proto.getName() + \"] contains malformed safe regex pattern: \"\n                        + e.getMessage());\n        }\n        return Matchers.HeaderMatcher.forSafeRegEx(\n              proto.getName(), safeRegExMatch, proto.getInvertMatch());\n      case RANGE_MATCH:\n        Matchers.HeaderMatcher.Range rangeMatch = Matchers.HeaderMatcher.Range.create(\n              proto.getRangeMatch().getStart(), proto.getRangeMatch().getEnd());\n        return Matchers.HeaderMatcher.forRange(\n              proto.getName(), rangeMatch, proto.getInvertMatch());\n      case PRESENT_MATCH:\n        return Matchers.HeaderMatcher.forPresent(\n              proto.getName(), proto.getPresentMatch(), proto.getInvertMatch());\n      case PREFIX_MATCH:\n        @SuppressWarnings(\"deprecation\") // gRFC A63: support indefinitely\n        String prefixMatch = proto.getPrefixMatch();\n        return Matchers.HeaderMatcher.forPrefix(\n              proto.getName(), prefixMatch, proto.getInvertMatch());","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/MatcherParser.java#L33-L69","documentation":"MatcherParser.parseHeaderMatcher compiles the Envoy HeaderMatcher's safe_regex pattern with java.util.regex.Pattern.compile. If the regex is syntactically invalid (PatternSyntaxException), it wraps the failure into an IllegalArgumentException naming the header and the underlying regex error. The xDS config contained a regex this JVM cannot compile.","triggerScenarios":"An LDS/RDS route configuration contains a header_match with safe_regex_match whose regex string fails java.util.regex compilation (e.g. invalid escapes, unbalanced groups, RE2-only syntax).","commonSituations":"Regexes authored for RE2/other engines (e.g. possessive quantifiers or \\p{...} differences) pasted into Envoy config; hand-edited control-plane config with a typo; control plane emitting Go-regexp syntax not valid in Java.","solutions":["Fix the regex in the xDS management server config so it is valid java.util.regex syntax","Test the pattern with Pattern.compile before deploying it to the control plane","Read the embedded PatternSyntaxException message (it pinpoints index and problem)","Avoid RE2/Go-only constructs; use Java-compatible equivalents"],"exampleFix":"// xDS config before\n{\"name\":\"x-tenant\",\"safe_regex_match\":{\"regex\":\"(?P<tenant>.*)\"}}\n// after (named groups unsupported in older Java regex handling here)\n{\"name\":\"x-tenant\",\"safe_regex_match\":{\"regex\":\".*\"}}","handlingStrategy":"validation","validationCode":"try { java.util.regex.Pattern.compile(regex); } catch (java.util.regex.PatternSyntaxException e) { /* reject before deploying to control plane */ }","typeGuard":"null","tryCatchPattern":"try { matcher = MatcherParser.parseHeaderMatcher(proto); }\ncatch (IllegalArgumentException e) { log.error(\"Bad header regex in route config\", e); failConfigLoad(); }","preventionTips":["Validate regexes with Pattern.compile at config-authoring time","Avoid RE2/Go-only regex syntax","Pin the Envoy API version between control plane and client","Test route configs in staging before rollout"],"tags":["xds","regex","config","validation"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}