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
- 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
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
- 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
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
- ca_certificate_provider_instance name
- ca_certificate_provider_instance or system_root_certs is…
- CertificateProvider instance name
- common-tls-context is required in downstream-tls-context
- common-tls-context is required in upstream-tls-context
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)