{"record":{"id":"41109f7a84abf56b","repo":"grpc/grpc-java","slug":"no-trust-roots-configured","errorCode":null,"errorMessage":"No trust roots configured","messagePattern":"No trust roots configured","errorType":"exception","errorClass":"CertificateException","httpStatus":null,"severity":"critical","filePath":"util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java","lineNumber":165,"sourceCode":"          \"Failed to find X509ExtendedTrustManager with default TrustManager algorithm \"\n              + TrustManagerFactory.getDefaultAlgorithm());\n    }\n    return delegateManager;\n  }\n\n  private void checkTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine,\n      Socket socket, boolean checkingServer) throws CertificateException {\n    if (chain == null || chain.length == 0) {\n      throw new IllegalArgumentException(\n          \"Want certificate verification but got null or empty certificates\");\n    }\n    if (sslEngine == null && socket == null) {\n      throw new CertificateException(NOT_ENOUGH_INFO_MESSAGE);\n    }\n    if (this.verification != Verification.INSECURELY_SKIP_ALL_VERIFICATION) {\n      X509ExtendedTrustManager currentDelegateManager = this.delegateManager;\n      if (currentDelegateManager == null) {\n        throw new CertificateException(\"No trust roots configured\");\n      }\n      if (checkingServer) {\n        String algorithm = this.verification == Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION\n            ? \"HTTPS\" : \"\";\n        if (sslEngine != null) {\n          SSLParameters sslParams = sslEngine.getSSLParameters();\n          sslParams.setEndpointIdentificationAlgorithm(algorithm);\n          sslEngine.setSSLParameters(sslParams);\n          currentDelegateManager.checkServerTrusted(chain, authType, sslEngine);\n        } else {\n          if (!(socket instanceof SSLSocket)) {\n            throw new CertificateException(\"socket is not a type of SSLSocket\");\n          }\n          SSLSocket sslSocket = (SSLSocket)socket;\n          SSLParameters sslParams = sslSocket.getSSLParameters();\n          sslParams.setEndpointIdentificationAlgorithm(algorithm);\n          sslSocket.setSSLParameters(sslParams);\n          currentDelegateManager.checkServerTrusted(chain, authType, sslSocket);","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java#L147-L183","documentation":"checkTrusted refuses to verify when this.delegateManager is null and verification is not INSECURELY_SKIP_ALL_VERIFICATION: there are no trust roots loaded to validate the chain against, so it throws CertificateException(\"No trust roots configured\"). This means the manager was used before (or without) configuring trust credentials.","triggerScenarios":"Performing a TLS verification via checkClientTrusted/checkServerTrusted before calling updateTrustCredentials(...) or useSystemDefaultTrustCerts(), or after those calls failed/were skipped, leaving delegateManager null.","commonSituations":"Forgetting the updateTrustCredentials/useSystemDefaultTrustCerts call during setup; a background refresh thread failed so the initial load never completed; updateTrustCredentials scheduled for future refresh but verification attempted immediately before the first call; system-default loading threw (see related delegate error) and the failure was swallowed.","solutions":["Call trustManager.updateTrustCredentials(CertificateType.FILE_PATH, path, refreshIntervalMs) or useSystemDefaultTrustCerts() before any connection is made.","Check the return/exception of updateTrustCredentials — if the initial load fails, delegateManager stays null; fix the underlying load error (missing file, bad password, no extended trust manager).","If you truly want no verification, explicitly call useInsecureSkipVerify() instead of leaving roots unset.","Await/wait for the initial trust configuration to complete (or perform it synchronously) before starting the gRPC channel."],"exampleFix":"// before\nAdvancedTlsX509TrustManager tm = new AdvancedTlsX509TrustManager(Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION);\nSslContext ctx = GrpcSslContexts.forClient().trustManager(tm).build();\n\n// after\nAdvancedTlsX509TrustManager tm = new AdvancedTlsX509TrustManager(Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION);\ntm.updateTrustCredentials(CertificateType.FILE_PATH, \"/path/to/ca.pem\", 60000);\nSslContext ctx = GrpcSslContexts.forClient().trustManager(tm).build();","handlingStrategy":"validation","validationCode":"// Configure trust roots before building the SslContext\ntrustManager.updateTrustCredentials(CertificateType.FILE_PATH, \"/path/to/ca.pem\", 60000);\nif (!trustManager.isShutdown() /* roots configured implicitly */) { /* proceed */ }\n// or defensively:\ntry {\n  trustManager.checkServerTrusted(new X509Certificate[]{placeholderCert}, \"TLS\", sslEngine);\n} catch (CertificateException e) {\n  if (e.getMessage().equals(\"No trust roots configured\")) {\n    throw new IllegalStateException(\"Call updateTrustCredentials or useSystemDefaultTrustCerts before connecting\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  channel = grpcManagedChannel(...);\n  stub.call(...);\n} catch (javax.net.ssl.SSLHandshakeException e) {\n  if (e.getCause() != null && String.valueOf(e.getCause().getMessage()).contains(\"No trust roots configured\")) {\n    throw new IllegalStateException(\"Trust roots not configured on AdvancedTlsX509TrustManager\", e);\n  }\n  throw e;\n}","preventionTips":["Always call updateTrustCredentials or useSystemDefaultTrustCerts immediately after constructing the manager, before opening channels.","Check the CA file path/permissions in your environment (config maps, containers) so the initial load cannot silently fail.","If skipping verification is intentional, call useInsecureSkipVerify() explicitly and never ship that in production.","Log failures from updateTrustCredentials instead of swallowing them; delegateManager remains null if the initial load throws.","Perform the initial trust-credential load synchronously before starting refresh scheduling."],"tags":["tls","certificate","trust-roots","configuration","grpc"],"backgroundTag":"missing-required-config","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"}