apache/pulsar · error
Invalid short topic name '%s', it should be in the format of
Error message
Invalid short topic name '%s', it should be in the format of <tenant>/<namespace>/<topic> or <topic>
What it means
ParseTopicName accepts either a fully qualified topic (persistent://tenant/namespace/topic) or a short topic name (<topic>) which is expanded using the default tenant/namespace. A name with 2 slash-separated segments (e.g. myns/mytopic) fits neither form, so parsing fails with this error.
Source
Thrown at pulsar-function-go/pf/topicName.go:58
partitionedTopicSuffix = "-partition-"
)
// ParseTopicName parse the given topic name and return TopicName.
func ParseTopicName(topic string) (*TopicName, error) {
// The topic name can be in two different forms, one is fully qualified topic name,
// the other one is short topic name
if !strings.Contains(topic, "://") {
// The short topic name can be:
// - <topic>
// - <tenant>/<namespace>/<topic>
// - <tenant>/<cluster>/<namespace>/<topic>
parts := strings.Split(topic, "/")
if len(parts) == 3 || len(parts) == 4 {
topic = "persistent://" + topic
} else if len(parts) == 1 {
topic = "persistent://" + publicTenant + "/" + defaultNamespace + "/" + parts[0]
} else {
return nil, errors.New(
"Invalid short topic name '" + topic +
"', it should be in the format of <tenant>/<namespace>/<topic> or <topic>")
}
}
tn := &TopicName{}
// The fully qualified topic name can be in two different forms:
// new: persistent://tenant/namespace/topic
// legacy: persistent://tenant/cluster/namespace/topic
parts := strings.SplitN(topic, "://", 2)
domain := parts[0]
if domain != "persistent" && domain != "non-persistent" {
return nil, errors.New("Invalid topic domain: " + domain)
}
tn.Domain = domain
rest := parts[1]View on GitHub (pinned to 820761864e)
Solutions
- Use the full short form: just the topic name, e.g. 'mytopic'
- Or use the fully qualified form: 'persistent://public/default/mytopic'
- Check the string for stray or missing slashes; 2 segments is always invalid
- In Java-interop configs use 'persistent://public/default/<topic>'
Example fix
// before
pf.ParseTopicName("public/mytopic") // error
// after
pf.ParseTopicName("persistent://public/default/mytopic") Defensive patterns
Strategy: validation
Validate before calling
segments := strings.Count(topic, "/") + 1
if segments != 1 && segments != 3 && segments != 4 {
return fmt.Errorf("topic %q must have 1, 3, or 4 slash-separated segments", topic)
} Type guard
func isShortTopic(t string) bool { return !strings.Contains(t, "://") && strings.Count(t, "/") == 0 } Try / catch
tn, err := pf.ParseTopicName(topic)
if err != nil {
return fmt.Errorf("parse topic %q: %w", topic, err)
} Prevention
- Prefer fully qualified persistent://tenant/namespace/topic names in configs
- Never pass tenant/namespace fragments (2 segments)
- Strip surrounding whitespace before parsing
When it happens
Trigger: Passing a topic like 'public/mytopic' or 'tenant/topic' (2 segments) to setupConsumer or respondMessage; only 1, 3, or 4 segments are valid.
Common situations: Developers supplying tenant/namespace fragments partially, splitting config strings incorrectly, or copying topic names from UI columns that omit the domain prefix.
Related errors
- Invalid topic name: %s
- Invalid topic domain: %s
- Input topic %s is invalid
- Output topic %s is invalid
- LogTopic topic %s is invalid
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/449f060ea4779c10.
Report an issue: GitHub.