{"record":{"id":"42ebcfa4fc98d370","repo":"apache/pulsar","slug":"testtopic-can-not-be-blank","errorCode":null,"errorMessage":"testTopic can not be blank","messagePattern":"testTopic can not be blank","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/SameAuthParamsLookupAutoClusterFailover.java","lineNumber":343,"sourceCode":"        public Builder recoverThreshold(int recoverThreshold) {\n            if (recoverThreshold < 1) {\n                throw new IllegalArgumentException(\"recoverThreshold must be larger than 0\");\n            }\n            sameAuthParamsLookupAutoClusterFailover.recoverThreshold = recoverThreshold;\n            return this;\n        }\n\n        public Builder checkHealthyIntervalMs(int checkHealthyIntervalMs) {\n            if (checkHealthyIntervalMs < 1) {\n                throw new IllegalArgumentException(\"checkHealthyIntervalMs must be larger than 0\");\n            }\n            sameAuthParamsLookupAutoClusterFailover.checkHealthyIntervalMs = checkHealthyIntervalMs;\n            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++) {","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/SameAuthParamsLookupAutoClusterFailover.java#L325-L361","documentation":"The Builder.testTopic(String) setter rejects a blank test topic. The probe uses this topic to check cluster health; a blank topic cannot be resolved. (Note the guard also calls TopicName.get(testTopic), which itself throws on a malformed topic string, so invalid topic formats surface here too.)","triggerScenarios":"Calling testTopic(null), testTopic(\"\"), or testTopic(\"   \") on the SameAuthParamsLookupAutoClusterFailover Builder, or passing a string that TopicName.get cannot parse.","commonSituations":"YAML/properties config where the test topic key is present but empty; environment variable not set and substituted as empty string; typo in the topic name format (missing persistent:// or namespace).","solutions":["Provide a fully qualified topic name such as persistent://public/default/__cluster_health_check.","In config loading, fail fast (with your own message) if the test-topic property is null/blank instead of passing it through.","Verify the topic string matches Pulsar's topic-name format (domain://tenant/namespace/topic)."],"exampleFix":"// before\nbuilder.testTopic(System.getenv(\"HEALTH_TOPIC\")); // null when unset\n\n// after\nString topic = System.getenv(\"HEALTH_TOPIC\");\nif (topic == null || topic.isBlank()) {\n    topic = \"persistent://public/default/__cluster_health_check\";\n}\nbuilder.testTopic(topic);","handlingStrategy":"validation","validationCode":"if (testTopic == null || testTopic.isBlank()) {\n    throw new IllegalArgumentException(\"testTopic must be set to a fully qualified topic name\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    builder.testTopic(topic);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Invalid testTopic '{}', using default\", topic, e);\n    builder.testTopic(\"persistent://public/default/__cluster_health_check\");\n}","preventionTips":["Always configure the health-check topic as a fully qualified persistent:// topic.","Fail fast in config loading when required topic properties are blank.","Ensure the probe topic exists in both clusters (auto-create or provision it)."],"tags":["pulsar-client","configuration","validation","illegal-argument","topic-name"],"backgroundTag":"invalid-topic-name","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"}