grpc/grpc-java · error · IllegalArgumentException

Not supported: ${specifierCase}

Error message

Not supported: ${specifierCase}

What it means

XdsTrustManagerFactory.getTrustedCaFromCertContext extracts trusted CA certificates from a CertificateValidationContext's trusted_ca. It supports only SPECIFIED (file/watched-directory via tls certificate provider paths, depending on implementation) and INLINE_BYTES specifier cases; any other oneof case (e.g. the field is unset or an unsupported source like watched_directory handled elsewhere / cert provider instance) reaches the else branch and throws IllegalArgumentException.

Source

Thrown at xds/src/main/java/io/grpc/xds/internal/security/trust/XdsTrustManagerFactory.java:125

  private static X509Certificate[] getTrustedCaFromCertContext(
      CertificateValidationContext certificateValidationContext)
      throws CertificateException, IOException {
    final SpecifierCase specifierCase =
        certificateValidationContext.getTrustedCa().getSpecifierCase();
    if (specifierCase == SpecifierCase.FILENAME) {
      String certsFile = certificateValidationContext.getTrustedCa().getFilename();
      checkState(
          !Strings.isNullOrEmpty(certsFile),
          "trustedCa.file-name in certificateValidationContext cannot be empty");
      return CertificateUtils.toX509Certificates(new File(certsFile));
    } else if (specifierCase == SpecifierCase.INLINE_BYTES) {
      try (InputStream is =
          certificateValidationContext.getTrustedCa().getInlineBytes().newInput()) {
        return CertificateUtils.toX509Certificates(is);
      }
    } else {
      throw new IllegalArgumentException("Not supported: " + specifierCase);
    }
  }

  @VisibleForTesting
  static XdsX509TrustManager createX509TrustManager(
      X509Certificate[] certs, CertificateValidationContext certContext,
      boolean autoSniSanValidation)
      throws CertStoreException {
    return new XdsX509TrustManager(certContext, createTrustManager(certs), autoSniSanValidation);
  }

  @VisibleForTesting
  static XdsX509TrustManager createX509TrustManager(
      Map<String, List<X509Certificate>> spiffeTrustMapFile,
      CertificateValidationContext certContext, boolean autoSniSanValidation)
      throws CertStoreException {
    checkNotNull(spiffeTrustMapFile, "spiffeTrustMapFile");
    Map<String, X509ExtendedTrustManager> delegates = new HashMap<>();

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Ensure the CertificateValidationContext's trusted_ca uses a supported source (inline_bytes or a supported file-based specified case)
  2. Populate trusted_ca via certificate provider instances instead if using cert-provider-based TLS, so this code path is not used
  3. Check that the xDS control plane sends a non-empty trusted_ca in the expected oneof case
  4. Upgrade grpc-java in case support for the specifier case you use was added later

Example fix

// before: empty trusted_ca in validation context
validation_context { } // SpecifierCase not set -> throws
// after
validation_context { trusted_ca { inline_bytes: "<PEM>" } }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure trusted_ca is set to a supported oneof case before building the trust manager
boolean trustedCaSupported(CertificateValidationContext cvc) {
  switch (cvc.getTrustedCa().getSpecifierCase()) {
    case INLINE_BYTES:
    case SPECIFIED:
      return true;
    default:
      return false;
  }
}

Try / catch

try {
  XdsX509TrustManager tm = XdsTrustManagerFactory.createX509TrustManager(certs, certContext);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Not supported:")) {
    logger.error("trusted_ca uses unsupported specifier case; set inline_bytes or supported file form", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Building an XdsX509TrustManager from a CertificateValidationContext where trusted_ca is set to a oneof case other than inline_bytes or the supported specified form — commonly when trusted_ca is simply not populated (SpecifierCase.SPECIFIERCASE_NOT_SET) or uses a newer API field the parser does not handle.

Common situations: Control plane sending validation contexts with empty trusted_ca; mesh configs relying on combined validation contexts or provider instances instead of a direct trusted_ca; xDS API version skew between server and grpc-java.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/40ecda2cecfe0dc2. Report an issue: GitHub.