apache/pulsar · error · IllegalArgumentException
Invalid short topic name '${completeTopicName}', it should b
Error message
Invalid short topic name '${completeTopicName}', it should be in the format of <tenant>/<namespace>/<topic> or <topic> What it means
TopicName.get()/the TopicName constructor parses a topic name given without a 'domain://' scheme (a 'short topic name'). Only two shapes are accepted: '<topic>' alone (defaults to public/default namespace, persistent domain) or the full '<tenant>/<namespace>/<topic>'. Any other slash-count (2 parts, 4+ parts, empty segments producing extra parts) makes the parser throw this IllegalArgumentException because the name is ambiguous.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/naming/TopicName.java:170
// The topic name can be in two different forms, one is fully qualified topic name,
// the other one is short topic name
int index = completeTopicName.indexOf("://");
if (index < 0) {
// The short topic name can be:
// - <topic>
// - <tenant>/<namespace>/<topic>
List<String> parts = splitBySlash(completeTopicName, 0);
this.domain = TopicDomain.persistent;
if (parts.size() == 3) {
this.tenant = parts.get(0);
this.namespacePortion = parts.get(1);
this.localName = parts.get(2);
} else if (parts.size() == 1) {
this.tenant = PUBLIC_TENANT;
this.namespacePortion = DEFAULT_NAMESPACE;
this.localName = parts.get(0);
} else {
throw new IllegalArgumentException(
"Invalid short topic name '" + completeTopicName + "', it should be in the format of "
+ "<tenant>/<namespace>/<topic> or <topic>");
}
this.segmentRange = null;
this.segmentId = -1;
this.completeTopicName = domain.name() + "://" + tenant + "/" + namespacePortion + "/" + localName;
} else {
this.domain = TopicDomain.getEnum(completeTopicName.substring(0, index));
// Scalable topic domains (topic://, segment://) only support the new format
// and local names may contain '/', so use limit(3) to keep the rest as localName.
boolean isScalableDomain = this.domain == TopicDomain.topic
|| this.domain == TopicDomain.segment;
int splitLimit = isScalableDomain ? 3 : 4;
List<String> parts = splitBySlash(completeTopicName.substring(index + "://".length()),
splitLimit);
if (parts.size() == 4) {
throw new IllegalArgumentException(
"V1 topic names (with cluster component) are no longer supported. "View on GitHub (pinned to 820761864e)
Solutions
- Use the full topic only ('my-topic') or the full 'tenant/namespace/topic' form
- Add the missing or remove the extra '/' segment so the name has exactly 1 or 3 slash-separated parts
- Use the fully-qualified form 'persistent://tenant/namespace/topic' to be unambiguous
- Trim whitespace and strip leading/trailing slashes before passing the name
Example fix
// before
TopicName.get("tenant/namespace");
// after
TopicName.get("persistent://tenant/namespace/my-topic"); Defensive patterns
Strategy: validation
Validate before calling
static boolean isShortTopicNameValid(String name) {
if (name == null || name.isEmpty()) return false;
String[] parts = name.split("/", -1);
return parts.length == 1 || (parts.length == 3 && parts[0].length() > 0
&& parts[1].length() > 0 && parts[2].length() > 0);
} Type guard
static boolean isUsableTopicName(String name) {
return name != null && (name.contains("://") || isShortTopicNameValid(name));
} Try / catch
try {
TopicName tn = TopicName.get(userTopic);
} catch (IllegalArgumentException e) {
log.warn("Rejected topic name '{}': {}", userTopic, e.getMessage());
throw new InvalidTopicNameException(userTopic);
} Prevention
- Always pass fully-qualified 'persistent://tenant/namespace/topic' names in configs and code
- Validate slash-count before constructing TopicName
- Trim whitespace and strip leading/trailing slashes from user input
- Never build topic names by raw string concatenation without a helper that normalizes the format
When it happens
Trigger: Calling TopicName.get(name) or any API accepting a topic string with a name like 'tenant/namespace' (missing topic), 'tenant/namespace/topic/partition' style with extra slashes, or 'my//topic' (empty segment).
Common situations: Config files or CLI flags where users supply 'tenant/namespace' without the topic; string concatenation that leaves a trailing slash; copying a namespace (not topic) from the UI; splitting/parsing code that drops the domain prefix but keeps V1 4-part names.
Related errors
- V1 topic names (with cluster component) are no longer suppor
- Invalid topic name ${completeTopicName}
- Invalid segment topic name: local name must contain '<parent
- Invalid segment descriptor: expected '<hexStart>-<hexEnd>-<s
- ResourceGroupCreate: Invalid null ResourceGroup config
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/8114f9038a944589.
Report an issue: GitHub.