grpc/grpc-java · error · ResourceInvalidException
verify_certificate_spki in default_validation_context is not
Error message
verify_certificate_spki in default_validation_context is not supported
What it means
gRPC xDS rejects a Cluster's upstream/downstream TLS context whose default_validation_context (CertificateValidationContext) contains verify_certificate_spki entries. SPKI-pin based certificate verification is not implemented by grpc-java's xDS transport security, so a resource carrying it is invalid and the xDS client rejects the whole cluster resource with ResourceInvalidException.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:511
+ "' 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");
}
if (certificateValidationContext.hasCustomValidatorConfig()) {
throw new ResourceInvalidException(
"custom_validator_config in default_validation_context is not supported");
}View on GitHub (pinned to 64daddc1f3)
Solutions
- Remove verify_certificate_spki from default_validation_context in the cluster's upstream_tls_context
- Pin trust via trust_ca / ca_certificate_provider_file (root CA validation) instead of SPKI pins
- Use match_subject_alt_names (upstream only) to restrict accepted server identities
- Check grpc-java xDS docs/issue tracker for SPKI support before relying on it
Example fix
# before (upstream_tls_context.common_tls_context.validation_context)
validation_context:
default_validation_context:
verify_certificate_spki:
- "57l7MLNM1zHwTdOCQ0mVcOatsCJw"
trust_ca: { ... }
# after
validation_context:
default_validation_context: {}
trust_ca: { ... }
match_subject_alt_names:
- { prefix: "srv.example.com" } Defensive patterns
Strategy: validation
Validate before calling
if (ctx.getDefaultValidationContext().getVerifyCertificateSpkiCount() > 0) {
throw new IllegalArgumentException("verify_certificate_spki unsupported by grpc-java xDS");
} Try / catch
try {
cluster = XdsClusterResource.parse(resource);
} catch (ResourceInvalidException e) {
logger.warn("Cluster rejected: {}", e.getMessage());
} Prevention
- Never copy Envoy CertificateValidationContext fields (spki/hash/crl/ct/custom validator) into grpc-java xDS configs
- Restrict upstream identity with match_subject_alt_names instead of pinning
- Keep trust anchored via trust_ca or ca_certificate_provider_file
- Review grpc-java xDS supported TLS fields per release
When it happens
Trigger: An LDS/CDS resource (via validateUpstreamTlsContext -> validateCommonTlsContext) sets CommonTlsContext.CertificateValidationContext.verify_certificate_spki (one or more base64 SPKI hashes) inside default_validation_context when configuring mTLS via upstream_tls_context.
Common situations: Envoy configs copied verbatim into gRPC xDS deployments; control planes (e.g. istiod, ads pipelines) generating Envoy-style CertificateValidationContext with SPKI pins; teams migrating from Envoy expecting feature parity in grpc-java xDS.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- verify_certificate_hash in default_validation_context is not
- require_signed_certificate_timestamp in default_validation_c
- custom_validator_config in default_validation_context is not
- TlsCredentials input stream construction pending.
- tls_certificate_provider_instance is required in downstream-
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/298d33abeb83f740.
Report an issue: GitHub.