apache/pulsar · error · IllegalArgumentException
Does not support topic domain:
Error message
Does not support topic domain:
What it means
Thrown by TopicList.removeTopicDomainScheme when the given string prefix does not end with a recognized topic domain ('persistent' or 'non-persistent') and is not empty. The method can only strip a topic domain scheme it knows; any other ending prefix is rejected with this IllegalArgumentException.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/topics/TopicList.java:128
s1.removeAll(list2);
return s1;
}
public static String removeTopicDomainScheme(String originalRegexp) {
if (!originalRegexp.toString().contains(SCHEME_SEPARATOR)) {
return originalRegexp;
}
String[] parts = SCHEME_SEPARATOR_PATTERN.split(originalRegexp.toString());
String prefix = parts[0];
String removedTopicDomain = parts[1];
if (prefix.equals(TopicDomain.persistent.value()) || prefix.equals(TopicDomain.non_persistent.value())) {
prefix = "";
} else if (prefix.endsWith(TopicDomain.non_persistent.value())) {
prefix = prefix.substring(0, prefix.length() - TopicDomain.non_persistent.value().length());
} else if (prefix.endsWith(TopicDomain.persistent.value())){
prefix = prefix.substring(0, prefix.length() - TopicDomain.persistent.value().length());
} else {
throw new IllegalArgumentException("Does not support topic domain: " + prefix);
}
return prefix + removedTopicDomain;
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Only call removeTopicDomainScheme on strings that include the 'persistent://' or 'non-persistent://' scheme
- Check/normalize the input first (endsWith check or TopicName validation) and skip stripping when no domain is present
- Fix typos and casing in the domain portion before calling
- Handle domain-less topics separately instead of routing them through this method
Example fix
// before
String name = TopicList.removeTopicDomainScheme(topic); // topic = "my-tenant/ns/my-topic"
// after
String name = topic.startsWith("persistent://") || topic.startsWith("non-persistent://")
? TopicList.removeTopicDomainScheme(topic)
: topic; Defensive patterns
Strategy: validation
Validate before calling
if (topic.startsWith("persistent://") || topic.startsWith("non-persistent://")) {
String stripped = TopicList.removeTopicDomainScheme(topic);
} Type guard
static boolean hasTopicDomain(String topic) {
return topic != null && (topic.startsWith("persistent://") || topic.startsWith("non-persistent://"));
} Try / catch
try {
stripped = TopicList.removeTopicDomainScheme(topic);
} catch (IllegalArgumentException e) {
stripped = topic; // treat as already domain-less
} Prevention
- Only strip the domain once — track whether it was already removed
- Normalize casing before calling (domains are lowercase)
- Validate topics with TopicName or regex before processing lists
- Never pass namespace-only or bare topic names into removeTopicDomainScheme
When it happens
Trigger: Calling removeTopicDomainScheme with a topic string or prefix that does not end in 'persistent/' or 'non-persistent/' — e.g. a plain topic name without a domain, a typo like 'persistant://', or a namespace-only string.
Common situations: Passing already-domain-stripped topics back into the function (double stripping); user-supplied topic lists mixing domainful and domain-less names; case mismatches ('Persistent://'); partitions or REST paths that omit the domain; custom tooling building topic names by hand.
Related errors
- byte string cannot be empty
- Invalid Fully Qualified Function Name
- Timeout during delete operation
- Timeout during close operation
- Timeout during open-cursor operation
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/b7a2043eac3c26a0.
Report an issue: GitHub.