{"record":{"id":"1aa70b605dd3ba35","repo":"grpc/grpc-java","slug":"unexpected-error-converting-channelcredentials-to","errorCode":null,"errorMessage":"Unexpected error converting ChannelCredentials to Netty SslContext: ${ex}","messagePattern":"Unexpected error converting ChannelCredentials to Netty SslContext: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java","lineNumber":783,"sourceCode":"\n\n\n  static Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {\n    return Collections.singleton(InetSocketAddress.class);\n  }\n\n  private final class DefaultProtocolNegotiator implements ProtocolNegotiator.ClientFactory {\n    private NegotiationType negotiationType = NegotiationType.TLS;\n    private SslContext sslContext;\n\n    @Override\n    public ProtocolNegotiator newNegotiator() {\n      SslContext localSslContext = sslContext;\n      if (negotiationType == NegotiationType.TLS && localSslContext == null) {\n        try {\n          localSslContext = GrpcSslContexts.forClient().build();\n        } catch (SSLException ex) {\n          throw new RuntimeException(ex);\n        }\n      }\n      return createProtocolNegotiatorByType(negotiationType, localSslContext,\n          managedChannelImplBuilder.getOffloadExecutorPool());\n    }\n\n    @Override\n    public int getDefaultPort() {\n      switch (negotiationType) {\n        case PLAINTEXT:\n        case PLAINTEXT_UPGRADE:\n          return GrpcUtil.DEFAULT_PORT_PLAINTEXT;\n        case TLS:\n          return GrpcUtil.DEFAULT_PORT_SSL;\n        default:\n          throw new AssertionError(negotiationType + \" not handled\");\n      }\n    }","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java#L765-L801","documentation":"When TLS is negotiated but no explicit SslContext was supplied, newNegotiator() builds a default client SslContext via GrpcSslContexts.forClient().build(). An SSLException during that build is wrapped and rethrown as an unchecked RuntimeException with message \"Unexpected error converting ChannelCredentials to Netty SslContext\" (the original SSLException as cause).","triggerScenarios":"Calling build() on a NettyChannelBuilder whose negotiationType is TLS with sslContext unset, when GrpcSslContexts.forClient().build() throws SSLException — typically due to missing TLS provider support, an empty/broken default trust manager setup, or an incompatible OpenSSL (netty-tcnative) configuration.","commonSituations":"Missing or mismatched netty-tcnative/boringssl native library so the default provider fails; JVM without the crypto primitives GrpcSslContexts expects; custom Conscrypt/tcnative versions conflicting; restricted crypto policy environments.","solutions":["Inspect the cause (SSLException) to find the underlying TLS provider problem.","Explicitly build and set an SslContext: GrpcSslContexts.forClient().trustManager(caFile).build(), then call sslContext(...) on the builder.","Add/align netty-tcnative-boringssl-static or Conscrypt with the netty version, or fall back to the JDK provider via SslProvider/JDK.","Ensure a full JDK (proper security providers, unlimited crypto policy) is used."],"exampleFix":"// before\nManagedChannel ch = NettyChannelBuilder.forAddress(\"host\", 443).build(); // TLS default, implicit SslContext\n// after\nSslContext sslCtx = GrpcSslContexts.forClient()\n    .trustManager(new File(\"ca.pem\"))\n    .build();\nManagedChannel ch = NettyChannelBuilder.forAddress(\"host\", 443)\n    .sslContext(sslCtx)\n    .build();","handlingStrategy":"try-catch","validationCode":"if (builder-useTls) {\n  try {\n    SslContext ctx = GrpcSslContexts.forClient().build(); // fail early, before channel build\n  } catch (SSLException e) { /* fix provider/trust setup */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n  ManagedChannel ch = builder.build();\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof SSLException) {\n    // TLS provider/environment problem: configure explicit SslContext or switch SslProvider\n  }\n}","preventionTips":["Ship netty-tcnative-boringssl-static matching your netty version","Set an explicit SslContext via sslContext(...) instead of relying on defaults","Test TLS client setup at startup, not lazily at first build()"],"tags":["grpc","java","tls","ssl-context"],"backgroundTag":"invalid-config-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"}