{"record":{"id":"90c42eb7d77c16a8","repo":"apache/pulsar","slug":"you-must-specify-tls-trust-store-type-tls-trust-s","errorCode":null,"errorMessage":"You must specify tls-trust-store-type, tls-trust-store and tls-trust-store-pwd when enable tls-enable-keystore","messagePattern":"You must specify tls-trust-store-type, tls-trust-store and tls-trust-store-pwd when enable tls-enable-keystore","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdClusters.java","lineNumber":90,"sourceCode":"    @Command(description = \"Provisions a new cluster. This operation requires Pulsar super-user privileges\")\n    private class Create extends CliCommand {\n        @ArgGroup(exclusive = false)\n        ClusterDetails clusterDetails = new ClusterDetails();\n\n        @Override\n        void run() throws PulsarAdminException, IOException {\n            getAdmin().clusters().createCluster(clusterDetails.clusterName, clusterDetails.getClusterData());\n        }\n\n    }\n\n    protected static void validateClusterData(ClusterData clusterData) {\n        if (clusterData.isBrokerClientTlsEnabled()) {\n            if (clusterData.isBrokerClientTlsEnabledWithKeyStore()) {\n                if (StringUtils.isAnyBlank(clusterData.getBrokerClientTlsTrustStoreType(),\n                        clusterData.getBrokerClientTlsTrustStore(),\n                        clusterData.getBrokerClientTlsTrustStorePassword())) {\n                    throw new RuntimeException(\n                            \"You must specify tls-trust-store-type, tls-trust-store and tls-trust-store-pwd\"\n                                    + \" when enable tls-enable-keystore\");\n                }\n            }\n        }\n    }\n\n    @Command(description = \"Update the configuration for a cluster\")\n    private class Update extends CliCommand {\n        @ArgGroup(exclusive = false)\n        ClusterDetails clusterDetails = new ClusterDetails();\n\n        @Override\n        void run() throws PulsarAdminException, IOException {\n            getAdmin().clusters().updateCluster(clusterDetails.clusterName, clusterDetails.getClusterData());\n        }\n\n    }","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdClusters.java#L72-L108","documentation":"validateClusterData checks ClusterData consistency before a cluster is created/updated. When TLS with keystores is enabled for broker client connections (tls-enable-keystore) the trust-store type, path, and password must all be provided; a RuntimeException is thrown when any of the three is blank. Keystore-based TLS cannot be set up without a complete trust store configuration.","triggerScenarios":"Running 'pulsar-admin clusters create/update' with --tls-enable-keystore (brokerClientTlsEnabledWithKeyStore=true) while omitting --tls-trust-store-type, --tls-trust-store, or --tls-trust-store-pwd (any one blank triggers it).","commonSituations":"Partially migrating a cluster config from certificate-based to keystore-based TLS and forgetting the password, or copying example commands that only set the trust store path.","solutions":["Provide all three options together: --tls-trust-store-type, --tls-trust-store, --tls-trust-store-pwd.","If keystore TLS is not needed, remove --tls-enable-keystore so the validation is skipped.","Set the same values persistently in the cluster data via the admin API (ClusterData brokerClientTlsTrustStore* fields)."],"exampleFix":"// before\npulsar-admin clusters update c1 --tls-enable-keystore --tls-trust-store /path/truststore.jks\n// after\npulsar-admin clusters update c1 --tls-enable-keystore --tls-trust-store-type JKS --tls-trust-store /path/truststore.jks --tls-trust-store-pwd secret","handlingStrategy":"validation","validationCode":"if (clusterData.isBrokerClientTlsEnabled() && clusterData.isBrokerClientTlsEnabledWithKeyStore()) {\n    boolean anyBlank = Stream.of(clusterData.getBrokerClientTlsTrustStoreType(),\n            clusterData.getBrokerClientTlsTrustStore(),\n            clusterData.getBrokerClientTlsTrustStorePassword()).anyMatch(StringUtils::isBlank);\n    if (anyBlank) throw new IllegalArgumentException(\"tls-trust-store-type, tls-trust-store and tls-trust-store-pwd are all required with keystore TLS\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.clusters().updateCluster(clusterData);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"tls-trust-store\")) {\n        System.err.println(\"Complete the keystore TLS config: type, store path and password are all required.\");\n    }\n}","preventionTips":["Treat the three trust-store options as one atomic group whenever --tls-enable-keystore is used.","Keep keystore TLS settings in a config file/template so they are set together.","Never commit the trust-store password; supply it from a secret at deploy time."],"tags":["cli","tls","configuration","validation"],"backgroundTag":"incomplete-tls-configuration","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}