{"record":{"id":"111de496d46e2e9b","repo":"alibaba/nacos","slug":"unable-to-build-sslcontext","errorCode":null,"errorMessage":"Unable to build SslContext","messagePattern":"Unable to build SslContext","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java","lineNumber":592,"sourceCode":"                Resource resource =\n                    resourceLoader.getResource(tlsConfig.getTrustCollectionCertFile());\n                builder.trustManager(resource.getInputStream());\n            }\n            \n            if (tlsConfig.getMutualAuthEnable()) {\n                if (StringUtils.isBlank(tlsConfig.getCertChainFile()) || StringUtils.isBlank(\n                    tlsConfig.getCertPrivateKey())) {\n                    throw new IllegalArgumentException(\n                        \"client certChainFile or certPrivateKey must be not null\");\n                }\n                Resource certChainFile = resourceLoader.getResource(tlsConfig.getCertChainFile());\n                Resource privateKey = resourceLoader.getResource(tlsConfig.getCertPrivateKey());\n                builder.keyManager(certChainFile.getInputStream(), privateKey.getInputStream(),\n                    tlsConfig.getCertPrivateKeyPassword());\n            }\n            return Optional.of(builder.build());\n        } catch (Exception e) {\n            throw new RuntimeException(\"Unable to build SslContext\", e);\n        }\n    }\n    \n    private ManagedChannelBuilder buildChannel(String serverIp, int port,\n        Optional<SslContext> sslContext) {\n        if (sslContext.isPresent()) {\n            return NettyChannelBuilder.forAddress(serverIp, port)\n                .negotiationType(NegotiationType.TLS)\n                .sslContext(sslContext.get());\n            \n        } else {\n            return ManagedChannelBuilder.forAddress(serverIp, port).usePlaintext();\n        }\n    }\n    \n    /**\n     * Setup response handler.\n     */","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java#L574-L610","documentation":"GrpcClient.buildSslContext() wraps any exception during SSL context construction (loading trust/key material, Netty SslContextBuilder.build(), unsupported protocol/cipher) in a RuntimeException 'Unable to build SslContext'. It is the catch-all for the whole TLS setup block, including the two IllegalArgumentExceptions (776, 777) when they escape, plus IO/parse failures on the PEM files.","triggerScenarios":"Any failure inside the try block of buildSslContext: unreadable cert/key files, malformed PEM, unsupported protocol specified, unsupported cipher, password mismatch on an encrypted key, or an error from Netty's SslContextBuilder.build().","commonSituations":"Cert/key file path wrong or unreadable; PEM format mismatch (PKCS#8 vs PKCS#1); protocols/ciphers list contains a value the OpenSSL/JDK provider rejects; private key password incorrect; provider (Conscrypt/OpenSSL) not on classpath; the underlying cause is chained in `e`.","solutions":["Read the wrapped cause (`e` in the catch) — it states the exact failure (FileNotFound, malformed PEM, unsupported cipher).","Confirm all referenced PEM files exist, are readable, and are in a supported format (PKCS#8 private key, PEM-encoded chain).","Validate the protocols/ciphers lists against what the runtime SSL provider supports; remove unsupported entries.","If a key is encrypted, supply the correct password via setCertPrivateKeyPassword().","Ensure the correct SSL provider JARs are on the classpath (netty-tcnative / Conscrypt) if you require specific protocols."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"static void validateTlsFilesReadable(RpcClientTlsConfig tls, ResourceLoader loader) throws IOException {\n    if (!isBlank(tls.getTrustCollectionCertFile()))\n        try (InputStream ignored = loader.getResource(tls.getTrustCollectionCertFile()).getInputStream()) {}\n    if (!isBlank(tls.getCertChainFile()))\n        try (InputStream ignored = loader.getResource(tls.getCertChainFile()).getInputStream()) {}\n    if (!isBlank(tls.getCertPrivateKey()))\n        try (InputStream ignored = loader.getResource(tls.getCertPrivateKey()).getInputStream()) {}\n}","typeGuard":null,"tryCatchPattern":"try {\n    client.start();\n} catch (RuntimeException re) {\n    if (\"Unable to build SslContext\".equals(re.getMessage())) {\n        Throwable cause = re.getCause(); // real reason: IO, malformed PEM, bad cipher\n        // fix cause, then retry\n    } else { throw re; }\n}","preventionTips":["Pre-validate all PEM file paths for existence and readability before start().","Confirm PEM formats are supported (PKCS#8 keys, PEM chains).","Cross-check protocols/ciphers against the runtime SSL provider; remove unsupported entries.","Always inspect the wrapped cause to identify the true SSL failure."],"tags":["grpc","tls","ssl","netty","certificates"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}