{"record":{"id":"36df76fa95fb0bd8","repo":"apache/pulsar","slug":"pulsarserviceurlarray-can-not-be-empty","errorCode":null,"errorMessage":"pulsarServiceUrlArray can not be empty","messagePattern":"pulsarServiceUrlArray can not be empty","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/SameAuthParamsLookupAutoClusterFailover.java","lineNumber":356,"sourceCode":"            return this;\n        }\n\n        public Builder testTopic(String testTopic) {\n            if (StringUtils.isBlank(testTopic) && TopicName.get(testTopic) != null) {\n                throw new IllegalArgumentException(\"testTopic can not be blank\");\n            }\n            sameAuthParamsLookupAutoClusterFailover.testTopic = testTopic;\n            return this;\n        }\n\n        public Builder markTopicNotFoundAsAvailable(boolean markTopicNotFoundAsAvailable) {\n            sameAuthParamsLookupAutoClusterFailover.markTopicNotFoundAsAvailable = markTopicNotFoundAsAvailable;\n            return this;\n        }\n\n        public Builder pulsarServiceUrlArray(String[] pulsarServiceUrlArray) {\n            if (pulsarServiceUrlArray == null || pulsarServiceUrlArray.length == 0) {\n                throw new IllegalArgumentException(\"pulsarServiceUrlArray can not be empty\");\n            }\n            sameAuthParamsLookupAutoClusterFailover.pulsarServiceUrlArray = pulsarServiceUrlArray;\n            int pulsarServiceLen = pulsarServiceUrlArray.length;\n            HashSet<String> uniqueChecker = new HashSet<>();\n            for (int i = 0; i < pulsarServiceLen; i++) {\n                String pulsarService = pulsarServiceUrlArray[i];\n                if (StringUtils.isBlank(pulsarService)) {\n                    throw new IllegalArgumentException(\"pulsarServiceUrlArray contains a blank value at index \" + i);\n                }\n                if (pulsarService.startsWith(\"http\") || pulsarService.startsWith(\"HTTP\")) {\n                    throw new IllegalArgumentException(\"SameAuthParamsLookupAutoClusterFailover does not support HTTP\"\n                            + \" protocol pulsar service url so far.\");\n                }\n                if (!uniqueChecker.add(pulsarService)) {\n                    throw new IllegalArgumentException(\"pulsarServiceUrlArray contains duplicated value \"\n                            + pulsarServiceUrlArray[i]);\n                }\n            }","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/SameAuthParamsLookupAutoClusterFailover.java#L338-L374","documentation":"Builder.pulsarServiceUrlArray(String[]) requires a non-null, non-empty array of Pulsar service URLs because the failover provider needs at least one cluster to fail over between. A null or zero-length array triggers IllegalArgumentException.","triggerScenarios":"Calling pulsarServiceUrlArray(null) or pulsarServiceUrlArray(new String[0]) on the SameAuthParamsLookupAutoClusterFailover Builder, e.g. when a comma-separated config list split to an empty array.","commonSituations":"Config property 'clusters=' empty or missing; splitting an empty string with String.split(\",\") and passing the result; programmatic construction before the cluster list is loaded from a registry.","solutions":["Pass an array with at least one valid pulsar+ssl:// (or pulsar://) service URL.","In config loading, check the cluster list size before building and surface a clear configuration error.","Use the standard single-cluster client setup if you only have one cluster — this failover provider is not needed."],"exampleFix":"// before\nString[] urls = cfg.get(\"clusters\", \"\").split(\",\");\nbuilder.pulsarServiceUrlArray(urls); // [\"\"] or empty\n\n// after\nString[] urls = Arrays.stream(cfg.get(\"clusters\", \"\").split(\",\"))\n    .map(String::trim).filter(s -> !s.isEmpty()).toArray(String[]::new);\nif (urls.length == 0) throw new IllegalArgumentException(\"At least one cluster URL is required\");\nbuilder.pulsarServiceUrlArray(urls);","handlingStrategy":"validation","validationCode":"String[] urls = parseUrls(cfg.getClusters());\nif (urls == null || urls.length == 0) {\n    throw new IllegalArgumentException(\"At least one cluster service URL is required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    builder.pulsarServiceUrlArray(urls);\n} catch (IllegalArgumentException e) {\n    log.error(\"Cluster URL list is empty; failover provider cannot start\", e);\n    throw new ConfigurationException(\"clusters must list at least one service URL\", e);\n}","preventionTips":["Require the cluster list config to be non-empty before constructing the provider.","Filter empty results after splitting comma-separated lists.","Use the plain single-cluster client when only one cluster is configured."],"tags":["pulsar-client","configuration","validation","illegal-argument"],"backgroundTag":"invalid-config-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}