grpc/grpc-java · error · ResourceInvalidException

ca_certificate_provider_instance or system_root_certs is…

Error message

ca_certificate_provider_instance or system_root_certs is required in upstream-tls-context

What it means

A client-side (upstream) TLS context must have a root of trust: either a ca_certificate_provider_instance or explicit use of system root certs. When getRootCertInstanceName returns null and system root certs are neither enabled nor applicable, the resource is rejected.

Solutions

  1. Set a ca_certificate_provider_instance in common_tls_context naming a bootstrap-defined provider with the CA cert.
  2. Enable system root certs and make the common_tls_context opt into them (empty validation_context / system root cert usage per gRFC A-65 style config).
  3. Use validation_context.trusted_ca inline if your control plane supports it for the client path.

Example fix

// before
"common_tls_context": { "tls_certificate_provider_instance": "identity-only" }
// after
"common_tls_context": {
  "tls_certificate_provider_instance": "google_cloud_private_spiffe",
  "combined_validation_context": { "default_validation_context": { "match_subject_alt_names": [ ... ] }, "validation_context_sds_secret_config": { "name": "ROOTCA" } }
}
Defensive patterns

Strategy: validation

Validate before calling

if (!isServerContext && !commonTlsContext.hasCaCertificateProviderInstance()
    && !CommonTlsContextUtil.isUsingSystemRootCerts(commonTlsContext)) {
  throw new IllegalArgumentException("upstream-tls-context needs a CA provider or system roots");
}

Try / catch

catch (ResourceInvalidException e) {
  if (e.getMessage().contains("ca_certificate_provider_instance or system_root_certs")) {
    // add CA provider or enable system root certs
  }
}

Prevention

When it happens

Trigger: server=false, rootCaInstanceName is null, and either enableSystemRootCerts is false or CommonTlsContextUtil.isUsingSystemRootCerts(commonTlsContext) is false (no validation_context.combined wildcard/empty trusted_ca indicating system roots).

Common situations: Upstream TLS context that supplies identity certs but no CA validation source; bootstraps where system_root_certs is disabled; resources migrated from an Envoy setup that trusted a proxy's CA via SDS.

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/2aa455b7db06235b. Report an issue: GitHub.

Appendix: source

Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:485

      }
      if (commonTlsContext.getTlsCertificatesCount() > 0) {
        throw new ResourceInvalidException(
            "tls_certificate_provider_instance is unset");
      }
      if (commonTlsContext.getTlsCertificateSdsSecretConfigsCount() > 0) {
        throw new ResourceInvalidException(
            "tls_certificate_provider_instance is unset");
      }
    } else if (certProviderInstances == null || !certProviderInstances.contains(certInstanceName)) {
      throw new ResourceInvalidException(
          "CertificateProvider instance name '" + certInstanceName
              + "' not defined in the bootstrap file.");
    }
    String rootCaInstanceName = getRootCertInstanceName(commonTlsContext);
    if (rootCaInstanceName == null) {
      if (!server && (!enableSystemRootCerts
          || !CommonTlsContextUtil.isUsingSystemRootCerts(commonTlsContext))) {
        throw new ResourceInvalidException(
            "ca_certificate_provider_instance or system_root_certs is required in "
                + "upstream-tls-context");
      }
    } 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) {

View on GitHub (pinned to 64daddc1f3)