{"record":{"id":"40ecda2cecfe0dc2","repo":"grpc/grpc-java","slug":"not-supported-specifiercase","errorCode":null,"errorMessage":"Not supported: ${specifierCase}","messagePattern":"Not supported: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/security/trust/XdsTrustManagerFactory.java","lineNumber":125,"sourceCode":"\n  private static X509Certificate[] getTrustedCaFromCertContext(\n      CertificateValidationContext certificateValidationContext)\n      throws CertificateException, IOException {\n    final SpecifierCase specifierCase =\n        certificateValidationContext.getTrustedCa().getSpecifierCase();\n    if (specifierCase == SpecifierCase.FILENAME) {\n      String certsFile = certificateValidationContext.getTrustedCa().getFilename();\n      checkState(\n          !Strings.isNullOrEmpty(certsFile),\n          \"trustedCa.file-name in certificateValidationContext cannot be empty\");\n      return CertificateUtils.toX509Certificates(new File(certsFile));\n    } else if (specifierCase == SpecifierCase.INLINE_BYTES) {\n      try (InputStream is =\n          certificateValidationContext.getTrustedCa().getInlineBytes().newInput()) {\n        return CertificateUtils.toX509Certificates(is);\n      }\n    } else {\n      throw new IllegalArgumentException(\"Not supported: \" + specifierCase);\n    }\n  }\n\n  @VisibleForTesting\n  static XdsX509TrustManager createX509TrustManager(\n      X509Certificate[] certs, CertificateValidationContext certContext,\n      boolean autoSniSanValidation)\n      throws CertStoreException {\n    return new XdsX509TrustManager(certContext, createTrustManager(certs), autoSniSanValidation);\n  }\n\n  @VisibleForTesting\n  static XdsX509TrustManager createX509TrustManager(\n      Map<String, List<X509Certificate>> spiffeTrustMapFile,\n      CertificateValidationContext certContext, boolean autoSniSanValidation)\n      throws CertStoreException {\n    checkNotNull(spiffeTrustMapFile, \"spiffeTrustMapFile\");\n    Map<String, X509ExtendedTrustManager> delegates = new HashMap<>();","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/security/trust/XdsTrustManagerFactory.java#L107-L143","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the CertificateValidationContext's trusted_ca uses a supported source (inline_bytes or a supported file-based specified case)","Populate trusted_ca via certificate provider instances instead if using cert-provider-based TLS, so this code path is not used","Check that the xDS control plane sends a non-empty trusted_ca in the expected oneof case","Upgrade grpc-java in case support for the specifier case you use was added later"],"exampleFix":"// before: empty trusted_ca in validation context\nvalidation_context { } // SpecifierCase not set -> throws\n// after\nvalidation_context { trusted_ca { inline_bytes: \"<PEM>\" } }","handlingStrategy":"validation","validationCode":"// Ensure trusted_ca is set to a supported oneof case before building the trust manager\nboolean trustedCaSupported(CertificateValidationContext cvc) {\n  switch (cvc.getTrustedCa().getSpecifierCase()) {\n    case INLINE_BYTES:\n    case SPECIFIED:\n      return true;\n    default:\n      return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  XdsX509TrustManager tm = XdsTrustManagerFactory.createX509TrustManager(certs, certContext);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Not supported:\")) {\n    logger.error(\"trusted_ca uses unsupported specifier case; set inline_bytes or supported file form\", e);\n  }\n  throw e;\n}","preventionTips":["Set trusted_ca explicitly (inline_bytes or supported specified form) in validation contexts","Prefer cert provider instances over inline trusted_ca for rotation-sensitive meshes","Keep xDS protobuf API versions aligned between control plane and grpc-java"],"tags":["xds","tls","trust-manager","grpc"],"backgroundTag":"unsupported-enum-value","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}