apache/pulsar · error

Invalid topic domain: %s

Error message

Invalid topic domain: %s

What it means

Topic-name parsing failure in the Go function runtime's ParseTopicName: after splitting on '://', the domain prefix is neither 'persistent' nor 'non-persistent' (the legacy 4-part cluster form is also handled separately), so the string is rejected as a topic name; the domain portion of the input string is the faulty input.

Source

Thrown at pulsar-function-go/pf/topicName.go:72

			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]
	var err error

	// The rest of the name can be in different forms:
	// new:    tenant/namespace/<localName>
	// legacy: tenant/cluster/namespace/<localName>
	// Examples of localName:
	// 1. some/name/xyz//
	// 2. /xyz-123/feeder-2
	parts = strings.SplitN(rest, "/", 4)
	if len(parts) == 3 {
		// New topic name without cluster name
		tn.Namespace = parts[0] + "/" + parts[1]
	} else if len(parts) == 4 {
		// Legacy topic name that includes cluster name

View on GitHub (pinned to 820761864e)

Solutions

  1. Use persistent:// or non-persistent:// as the topic scheme
  2. Fix typos in the topic URI

Example fix

// before
pf.ParseTopicName("kafka://my-tenant/ns/my-topic")
// after
pf.ParseTopicName("persistent://my-tenant/ns/my-topic")
Defensive patterns

Strategy: validation

Validate before calling

if i := strings.Index(topic, "://"); i >= 0 && topic[:i] != "persistent" && topic[:i] != "non-persistent" {
    return fmt.Errorf("unsupported domain %q", topic[:i])
}

Type guard

func isPulsarTopic(t string) bool { return strings.HasPrefix(t, "persistent://") || strings.HasPrefix(t, "non-persistent://") }

Try / catch

tn, err := pf.ParseTopicName(topic)
if err != nil {
    return fmt.Errorf("invalid topic domain in %q: %w", topic, err)
}

Prevention

When it happens

Trigger: Passing topics like 'kafka://my-topic', 'http://...', 'topic://x', or a typo such as 'persistant://tenant/ns/topic' to ParseTopicName.

Common situations: Copying URIs from other systems, typos in the scheme, or passing plain broker/service URLs instead of topic names.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/c6ca716795280118. Report an issue: GitHub.