{"record":{"id":"2132483523a39aae","repo":"alibaba/nacos","slug":"trustcollectioncertfile-must-be-not-null","errorCode":null,"errorMessage":"trustCollectionCertFile must be not null","messagePattern":"trustCollectionCertFile must be not null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java","lineNumber":572,"sourceCode":"            return Optional.empty();\n        }\n        try {\n            SslContextBuilder builder = GrpcSslContexts.forClient();\n            if (StringUtils.isNotBlank(tlsConfig.getSslProvider())) {\n                builder.sslProvider(TlsTypeResolve.getSslProvider(tlsConfig.getSslProvider()));\n            }\n            \n            if (StringUtils.isNotBlank(tlsConfig.getProtocols())) {\n                builder.protocols(tlsConfig.getProtocols().split(\",\"));\n            }\n            if (StringUtils.isNotBlank(tlsConfig.getCiphers())) {\n                builder.ciphers(Arrays.asList(tlsConfig.getCiphers().split(\",\")));\n            }\n            if (tlsConfig.getTrustAll()) {\n                builder.trustManager(InsecureTrustManagerFactory.INSTANCE);\n            } else {\n                if (StringUtils.isBlank(tlsConfig.getTrustCollectionCertFile())) {\n                    throw new IllegalArgumentException(\"trustCollectionCertFile must be not null\");\n                }\n                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());","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/common/src/main/java/com/alibaba/nacos/common/remote/client/grpc/GrpcClient.java#L554-L590","documentation":"GrpcClient.buildSslContext() requires a trust store when trustAll is disabled: with trustAll=false it must load `trustCollectionCertFile` to verify the server. If that field is blank, it throws IllegalArgumentException before attempting to load the trust material.","triggerScenarios":"Constructing an RpcClientTlsConfig with enableTls=true and trustAll=false (or unset, defaulting false), then starting the client so buildSslContext() runs. The blank check on getTrustCollectionCertFile() fails.","commonSituations":"Enabling TLS but forgetting to point to the CA trust-collection PEM; pointing to a system property that resolved to empty; YAML key typo (e.g. trustCollectionCertFile vs trustCollectionCert) leaving the field null; assuming a default trust store exists (none does in this builder path).","solutions":["Set tlsConfig.setTrustCollectionCertFile() to a valid PEM file path (or a classpath: URL the ResourceLoader can resolve).","Alternatively, set tlsConfig.setTrustAll(true) for development only when you cannot supply a CA file.","Double-check the YAML/property key name matches the setter exactly.","Verify the file is readable by the process (permissions, path)."],"exampleFix":"// before — TLS on, trustAll off, no CA file\nRpcClientTlsConfig tls = new RpcClientTlsConfig();\ntls.setEnableTls(true);\n\n// after — supply trust collection\nRpcClientTlsConfig tls = new RpcClientTlsConfig();\ntls.setEnableTls(true);\ntls.setTrustCollectionCertFile(\"/etc/nacos/certs/ca.pem\");","handlingStrategy":"validation","validationCode":"static void validateTls(RpcClientTlsConfig tls) {\n    if (tls.getEnableTls() != null && tls.getEnableTls() && !Boolean.TRUE.equals(tls.getTrustAll())) {\n        if (tls.getTrustCollectionCertFile() == null || tls.getTrustCollectionCertFile().isBlank()) {\n            throw new IllegalArgumentException(\n                \"TLS enabled without trustAll: must set trustCollectionCertFile\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    client.start();\n} catch (RuntimeException re) {\n    if (re.getMessage().contains(\"trustCollectionCertFile\")) {\n        // set the CA file or enable trustAll, then retry\n    } else { throw re; }\n}","preventionTips":["Validate TLS config before client.start() — trustAll=false requires a CA file.","Keep a checklist of required TLS fields for each mode (one-way vs mTLS).","Use a config validator in tests to catch blank TLS fields at build time."],"tags":["grpc","tls","ssl","truststore","config"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}