grpc/grpc-java · error · ResourceInvalidException
match_subject_alt_names only allowed in upstream_tls_context
Error message
match_subject_alt_names only allowed in upstream_tls_context
What it means
Subject alternative name matching (match_subject_alt_names) is only supported on the client side (upstream_tls_context), where gRPC validates the server identity. Server-side (downstream) validation contexts cannot restrict client SANs, so a non-empty list in a server context invalidates the resource.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:507
} else {
if (certProviderInstances == null || !certProviderInstances.contains(rootCaInstanceName)) {
throw new ResourceInvalidException(
"ca_certificate_provider_instance name '" + rootCaInstanceName
+ "' not defined in the bootstrap file.");
}
CertificateValidationContext certificateValidationContext = null;
if (commonTlsContext.hasValidationContext()) {
certificateValidationContext = commonTlsContext.getValidationContext();
} else if (commonTlsContext.hasCombinedValidationContext() && commonTlsContext
.getCombinedValidationContext().hasDefaultValidationContext()) {
certificateValidationContext = commonTlsContext.getCombinedValidationContext()
.getDefaultValidationContext();
}
if (certificateValidationContext != null) {
@SuppressWarnings("deprecation") // gRFC A29 predates match_typed_subject_alt_names
int matchSubjectAltNamesCount = certificateValidationContext.getMatchSubjectAltNamesCount();
if (matchSubjectAltNamesCount > 0 && server) {
throw new ResourceInvalidException(
"match_subject_alt_names only allowed in upstream_tls_context");
}
if (certificateValidationContext.getVerifyCertificateSpkiCount() > 0) {
throw new ResourceInvalidException(
"verify_certificate_spki in default_validation_context is not supported");
}
if (certificateValidationContext.getVerifyCertificateHashCount() > 0) {
throw new ResourceInvalidException(
"verify_certificate_hash in default_validation_context is not supported");
}
if (certificateValidationContext.hasRequireSignedCertificateTimestamp()) {
throw new ResourceInvalidException(
"require_signed_certificate_timestamp in default_validation_context is not "
+ "supported");
}
if (certificateValidationContext.hasCrl()) {
throw new ResourceInvalidException("crl in default_validation_context is not supported");
}View on GitHub (pinned to 64daddc1f3)
Solutions
- Remove match_subject_alt_names entries from the server-side validation context; authenticate clients via cert-provider-backed validation or application-level auth.
- Keep match_subject_alt_names only in upstream_tls_context where client-side server-identity checking is done.
- If peer identity enforcement is required server-side, use authorization (xDS RBAC/LDS) or in-process TLS peer verification via AuthContext after connection.
Example fix
// before (server downstream_tls_context)
"common_tls_context": {
"tls_certificate_provider_instance": "server-certs",
"combined_validation_context": { "default_validation_context": { "match_subject_alt_names": [ { "prefix": "spiffe://" } ] } }
}
// after
"common_tls_context": {
"tls_certificate_provider_instance": "server-certs",
"combined_validation_context": { "default_validation_context": {} }
} Defensive patterns
Strategy: validation
Validate before calling
if (isServerContext && validationCtx.getMatchSubjectAltNamesCount() > 0) {
throw new IllegalArgumentException("match_subject_alt_names only valid in upstream_tls_context");
} Try / catch
catch (ResourceInvalidException e) {
if (e.getMessage().contains("match_subject_alt_names only allowed")) {
// regenerate server-side validation context without SAN matchers
}
} Prevention
- Use separate TLS context templates for client and server directions.
- Enforce client identity server-side via xDS authorization or application-level checks instead of SAN matching.
When it happens
Trigger: server=true (downstream_tls_context validation) and certificateValidationContext.getMatchSubjectAltNamesCount() > 0 in validation_context, combined_validation_context's default, or default_validation_context (XdsClusterResource.java:507).
Common situations: Copying a client TLS context (with SAN allow-lists) into a server listener config; control planes that emit the same validation context template for both directions.
Related errors
- tls_certificate_provider_instance is required in downstream-
- common-tls-context is required in upstream-tls-context
- common-tls-context with custom_handshaker is not supported
- common-tls-context with tls_params is not supported
- common-tls-context with validation_context_sds_secret_config
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/f21b4c0117515e80.
Report an issue: GitHub.