grpc/grpc-java · error · ResourceInvalidException
common-tls-context is required in downstream-tls-context
Error message
common-tls-context is required in downstream-tls-context
What it means
A downstream TLS context must nest its configuration inside a common_tls_context; a DownstreamTlsContext without common_tls_context set cannot yield any certificates or validation parameters, so validateDownstreamTlsContext throws ResourceInvalidException. This is part of strict server-side TLS context validation before a filter chain is accepted.
Solutions
- Populate common_tls_context inside downstream_tls_context with tls_certificate (or tls_certificate_sds_secret_configs) and validation_context
- If using SDS, reference the certificate provider instances recognized by gRPC (matching certProviderInstances names) inside common_tls_context
- Validate the LDS resource with an Envoy-compatible validator before serving it to gRPC clients
Example fix
# before
downstream_tls_context:
require_client_certificate: true
# after
downstream_tls_context:
common_tls_context:
tls_certificates:
- certificate_chain: {filename: server.crt}
private_key: {filename: server.key} Defensive patterns
Strategy: validation
Validate before calling
if (fc.hasTransportSocket() && fc.getTransportSocket().hasTypedConfig()) {
DownstreamTlsContext tls = fc.getTransportSocket().getTypedConfig()
.unpack(DownstreamTlsContext.class); // may throw InvalidProtocolBufferException
if (!tls.hasCommonTlsContext()) {
throw new IllegalArgumentException("downstream_tls_context missing common_tls_context");
}
} Try / catch
try {
listener = XdsListenerResource.parseServerSideListener(proto, ...);
} catch (ResourceInvalidException e) {
if (e.getMessage().contains("common-tls-context is required")) {
logger.warn("Add common_tls_context to downstream_tls_context", e);
}
} Prevention
- Always nest server certs and validation under common_tls_context
- Reference SDS/certificate provider instance names that exist in the bootstrap
- Validate TLS context protos before publishing LDS resources
When it happens
Trigger: A FilterChain's transport_socket carries a DownstreamTlsContext message where the common_tls_context field is unset (hasCommonTlsContext() is false), passed through parseFilterChain into validateDownstreamTlsContext.
Common situations: Configs that set only fields like require_client_certificate or ocsp_staple_policy at the downstream level and forget common_tls_context; truncated control-plane templates; users porting upstream (client) TLS configs incorrectly.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
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 upstream-tls-context
- common-tls-context with custom_handshaker is not supported
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/e765f92a4901bd4a.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/XdsListenerResource.java:302
}
return FilterChain.create(
filterChainName,
filterChainMatch,
httpConnectionManager,
downstreamTlsContext,
tlsContextManager
);
}
@VisibleForTesting
static DownstreamTlsContext validateDownstreamTlsContext(
DownstreamTlsContext downstreamTlsContext, Set<String> certProviderInstances)
throws ResourceInvalidException {
if (downstreamTlsContext.hasCommonTlsContext()) {
validateCommonTlsContext(downstreamTlsContext.getCommonTlsContext(), certProviderInstances,
true);
} else {
throw new ResourceInvalidException(
"common-tls-context is required in downstream-tls-context");
}
if (downstreamTlsContext.hasRequireSni()) {
throw new ResourceInvalidException(
"downstream-tls-context with require-sni is not supported");
}
DownstreamTlsContext.OcspStaplePolicy ocspStaplePolicy = downstreamTlsContext
.getOcspStaplePolicy();
if (ocspStaplePolicy != DownstreamTlsContext.OcspStaplePolicy.UNRECOGNIZED
&& ocspStaplePolicy != DownstreamTlsContext.OcspStaplePolicy.LENIENT_STAPLING) {
throw new ResourceInvalidException(
"downstream-tls-context with ocsp_staple_policy value " + ocspStaplePolicy.name()
+ " is not supported");
}
return downstreamTlsContext;
}
View on GitHub (pinned to 64daddc1f3)