grpc/grpc-java · error · IllegalArgumentException

Unknown match-pattern-case

Error message

Unknown match-pattern-case ${matchPatternCase}

What it means

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.

Solutions

  1. Set a valid match pattern field (exact, safe_regex, prefix, suffix, or contains) on each san_matcher entry in the validation context
  2. Upgrade grpc-java/xDS protobuf libs so newer MatchPattern cases are supported
  3. Validate the CertificateValidationContext config before deployment to ensure every SAN matcher defines exactly one match pattern
  4. Log the full matcher proto when this occurs to identify the control plane emitting the invalid entry

Example fix

// before: matcher without a pattern
{"san_matcher": [{}} // no match_pattern set
// after
{"san_matcher": [{"exact": "foo.example.com"}]}
Defensive patterns

Strategy: validation

Validate before calling

// Verify each san_matcher sets exactly one known match pattern before deploying config
boolean knownPattern(StringMatcher m) {
  switch (m.getMatchPatternCase()) {
    case EXACT:
    case SAFE_REGEX:
    case PREFIX:
    case SUFFIX:
    case CONTAINS:
      return true;
    default:
      return false;
  }
}

Try / catch

try {
  handshake.verifyPeer(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Unknown match-pattern-case")) {
    logger.error("SAN matcher missing/unknown match_pattern; check control plane config and API versions", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java:109

      return false;
    }
    switch (sanToVerifyMatcher.getMatchPatternCase()) {
      case EXACT:
        return verifyDnsNameExact(
            altNameFromCert, sanToVerifyMatcher.getExact(), sanToVerifyMatcher.getIgnoreCase());
      case PREFIX:
        return verifyDnsNamePrefix(
            altNameFromCert, sanToVerifyMatcher.getPrefix(), sanToVerifyMatcher.getIgnoreCase());
      case SUFFIX:
        return verifyDnsNameSuffix(
            altNameFromCert, sanToVerifyMatcher.getSuffix(), sanToVerifyMatcher.getIgnoreCase());
      case CONTAINS:
        return verifyDnsNameContains(
            altNameFromCert, sanToVerifyMatcher.getContains(), sanToVerifyMatcher.getIgnoreCase());
      case SAFE_REGEX:
        return verifyDnsNameSafeRegex(altNameFromCert, sanToVerifyMatcher.getSafeRegex());
      default:
        throw new IllegalArgumentException(
            "Unknown match-pattern-case " + sanToVerifyMatcher.getMatchPatternCase());
    }
  }

  private static boolean verifyDnsNameSafeRegex(
          String altNameFromCert, RegexMatcher sanToVerifySafeRegex) {
    Pattern safeRegExMatch = Pattern.compile(sanToVerifySafeRegex.getRegex());
    return safeRegExMatch.matches(altNameFromCert);
  }

  private static boolean verifyDnsNamePrefix(
      String altNameFromCert, String sanToVerifyPrefix, boolean ignoreCase) {
    if (Strings.isNullOrEmpty(sanToVerifyPrefix)) {
      return false;
    }
    return ignoreCase
        ? altNameFromCert.toLowerCase(Locale.ROOT).startsWith(
            sanToVerifyPrefix.toLowerCase(Locale.ROOT))

View on GitHub (pinned to 64daddc1f3)