{"record":{"id":"e1c3ba42151f129e","repo":"apache/pulsar","slug":"invalid-topic-name-topic","errorCode":null,"errorMessage":"Invalid topic name ${topic}","messagePattern":"Invalid topic name (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/naming/TopicName.java","lineNumber":600,"sourceCode":"                }\n                return \"persistent://\" + topic;\n            }\n        }\n    }\n\n    private static List<String> splitBySlash(String topic, int limit) {\n        final List<String> tokens = new ArrayList<>(3);\n        final int loopCount = (limit <= 0) ? Integer.MAX_VALUE : limit - 1;\n        int beginIndex = 0;\n        for (int i = 0; i < loopCount; i++) {\n            final int endIndex = topic.indexOf('/', beginIndex);\n            if (endIndex < 0) {\n                tokens.add(topic.substring(beginIndex));\n                return tokens;\n            } else if (endIndex > beginIndex) {\n                tokens.add(topic.substring(beginIndex, endIndex));\n            } else {\n                throw new IllegalArgumentException(\"Invalid topic name \" + topic);\n            }\n            beginIndex = endIndex + 1;\n        }\n        if (beginIndex >= topic.length()) {\n            throw new IllegalArgumentException(\"Invalid topic name \" + topic);\n        }\n        tokens.add(topic.substring(beginIndex));\n        return tokens;\n    }\n}\n","sourceCodeStart":582,"sourceCodeEnd":611,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/naming/TopicName.java#L582-L611","documentation":"splitBySlash is TopicName's internal tokenizer used by toFullTopicName to split a topic string into path segments. It rejects strings containing empty segments (consecutive slashes, e.g. 'a//b') and strings ending with a trailing slash (nothing after the last '/'), throwing 'Invalid topic name <topic>' because empty tokens would silently produce malformed topic names.","triggerScenarios":"Any toFullTopicName() call whose input contains consecutive slashes or a trailing slash, e.g. 'persistent://tenant//topic' or 'tenant/ns/topic/' — splitBySlash hits an empty token and throws. The message surfaces as 'Invalid topic name <topic>'.","commonSituations":"URL-join logic that appends or duplicates slashes; base-URL + path concatenation bugs ('.../default/' + '/topic'); users pasting REST paths with trailing slashes; template substitution leaving empty segments.","solutions":["Remove duplicate/trailing slashes so each '/'-separated segment is non-empty","Normalize the topic string (e.g. collapse '//' to '/' and strip a trailing '/') before passing it","Use a full, well-formed 'persistent://tenant/ns/topic' URL"],"exampleFix":"// before\nTopicName.toFullTopicName(\"persistent://public/default//my-topic/\");\n// after\nString t = raw.replaceAll(\"/+\", \"/\").replaceAll(\"/$\", \"\");\nTopicName.toFullTopicName(t); // persistent://public/default/my-topic","handlingStrategy":"validation","validationCode":"public static boolean hasNoEmptySegments(String s) {\n    return s != null && !s.contains(\"//\") && !s.endsWith(\"/\") && !s.startsWith(\"/\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String full = TopicName.toFullTopicName(raw);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Invalid topic name\")) {\n        raw = raw.replaceAll(\"/+\", \"/\").replaceAll(\"/$\", \"\");\n        full = TopicName.toFullTopicName(raw);\n    }\n}","preventionTips":["Normalize topic strings: collapse consecutive slashes and strip trailing '/'","Beware of URL-join helpers that add slashes on both sides","Validate no empty path segments before passing names to Pulsar APIs"],"tags":["java","topic-naming","parsing"],"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"}