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

  1. Populate common_tls_context inside downstream_tls_context with tls_certificate (or tls_certificate_sds_secret_configs) and validation_context
  2. If using SDS, reference the certificate provider instances recognized by gRPC (matching certProviderInstances names) inside common_tls_context
  3. 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

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.

Related errors


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)