{"record":{"id":"b9f54290671602da","repo":"grpc/grpc-java","slug":"unknown-match-pattern-case-matchpatterncase","errorCode":null,"errorMessage":"Unknown match-pattern-case ${matchPatternCase}","messagePattern":"Unknown match-pattern-case (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java","lineNumber":109,"sourceCode":"      return false;\n    }\n    switch (sanToVerifyMatcher.getMatchPatternCase()) {\n      case EXACT:\n        return verifyDnsNameExact(\n            altNameFromCert, sanToVerifyMatcher.getExact(), sanToVerifyMatcher.getIgnoreCase());\n      case PREFIX:\n        return verifyDnsNamePrefix(\n            altNameFromCert, sanToVerifyMatcher.getPrefix(), sanToVerifyMatcher.getIgnoreCase());\n      case SUFFIX:\n        return verifyDnsNameSuffix(\n            altNameFromCert, sanToVerifyMatcher.getSuffix(), sanToVerifyMatcher.getIgnoreCase());\n      case CONTAINS:\n        return verifyDnsNameContains(\n            altNameFromCert, sanToVerifyMatcher.getContains(), sanToVerifyMatcher.getIgnoreCase());\n      case SAFE_REGEX:\n        return verifyDnsNameSafeRegex(altNameFromCert, sanToVerifyMatcher.getSafeRegex());\n      default:\n        throw new IllegalArgumentException(\n            \"Unknown match-pattern-case \" + sanToVerifyMatcher.getMatchPatternCase());\n    }\n  }\n\n  private static boolean verifyDnsNameSafeRegex(\n          String altNameFromCert, RegexMatcher sanToVerifySafeRegex) {\n    Pattern safeRegExMatch = Pattern.compile(sanToVerifySafeRegex.getRegex());\n    return safeRegExMatch.matches(altNameFromCert);\n  }\n\n  private static boolean verifyDnsNamePrefix(\n      String altNameFromCert, String sanToVerifyPrefix, boolean ignoreCase) {\n    if (Strings.isNullOrEmpty(sanToVerifyPrefix)) {\n      return false;\n    }\n    return ignoreCase\n        ? altNameFromCert.toLowerCase(Locale.ROOT).startsWith(\n            sanToVerifyPrefix.toLowerCase(Locale.ROOT))","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java#L91-L127","documentation":"XdsX509TrustManager.verifyDnsNameInPattern evaluates SAN matchers per Envoy's SAN verification semantics. The match_pattern oneof supports exact, suffix/prefix, contains, and safe_regex cases; any other MatchPatternCase (typically the oneof being unset) reaches the default branch and throws IllegalArgumentException naming the unknown case number.","triggerScenarios":"TLS certificate SAN verification against an xDS matcher whose san_matcher entry has no recognized match_pattern set (SPECIFIERCASE_NOT_SET) or an unknown oneof tag from API version skew; called from verifyDnsNameInSanList during peer certificate verification.","commonSituations":"Control plane sending san_matcher entries without setting a match pattern field; newer Envoy/protobuf versions introducing new match cases not yet handled by this grpc-java version; malformed xDS security config.","solutions":["Set a valid match pattern field (exact, safe_regex, prefix, suffix, or contains) on each san_matcher entry in the validation context","Upgrade grpc-java/xDS protobuf libs so newer MatchPattern cases are supported","Validate the CertificateValidationContext config before deployment to ensure every SAN matcher defines exactly one match pattern","Log the full matcher proto when this occurs to identify the control plane emitting the invalid entry"],"exampleFix":"// before: matcher without a pattern\n{\"san_matcher\": [{}} // no match_pattern set\n// after\n{\"san_matcher\": [{\"exact\": \"foo.example.com\"}]}","handlingStrategy":"validation","validationCode":"// Verify each san_matcher sets exactly one known match pattern before deploying config\nboolean knownPattern(StringMatcher m) {\n  switch (m.getMatchPatternCase()) {\n    case EXACT:\n    case SAFE_REGEX:\n    case PREFIX:\n    case SUFFIX:\n    case CONTAINS:\n      return true;\n    default:\n      return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  handshake.verifyPeer(...);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Unknown match-pattern-case\")) {\n    logger.error(\"SAN matcher missing/unknown match_pattern; check control plane config and API versions\", e);\n  }\n  throw e;\n}","preventionTips":["Always set exactly one match pattern field per san_matcher entry","Keep grpc-java and xDS protobuf versions up to date with the control plane","Validate CertificateValidationContext configs in CI before rollout"],"tags":["xds","tls","san-verification","grpc"],"backgroundTag":"invalid-enum-value","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"}