apache/pulsar · error · IllegalArgumentException
Invalid namespace format. expected <tenant>/<namespace> but
Error message
Invalid namespace format. expected <tenant>/<namespace> but got: ${namespace} What it means
This is the outer wrapper thrown by the NamespaceName constructor's catch block: any IllegalArgumentException (including the V1-unsupported and bad-format messages) or NullPointerException raised while parsing is rethrown with the message 'Invalid namespace format. expected <tenant>/<namespace> but got: <input>'. It tells the developer the library expects exactly '<tenant>/<namespace>'.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/naming/NamespaceName.java:107
// Verify it's a proper namespace
// The namespace name is composed of <tenant>/<namespace>
try {
String[] parts = namespace.split("/");
if (parts.length == 2) {
validateNamespaceName(parts[0], parts[1]);
tenant = parts[0];
localName = parts[1];
} else if (parts.length == 3) {
throw new IllegalArgumentException(
"V1 namespace names (with cluster component) are no longer supported. "
+ "Please use the V2 format: '<tenant>/<namespace>'. Got: " + namespace);
} else {
throw new IllegalArgumentException("Invalid namespace format. namespace: " + namespace);
}
} catch (IllegalArgumentException | NullPointerException e) {
throw new IllegalArgumentException("Invalid namespace format."
+ " expected <tenant>/<namespace>"
+ " but got: " + namespace, e);
}
this.namespace = namespace;
}
public String getTenant() {
return tenant;
}
public String getLocalName() {
return localName;
}
public String getPersistentTopicName(String localTopic) {
return getTopicName(TopicDomain.persistent, localTopic);
}
View on GitHub (pinned to 820761864e)
Solutions
- Inspect the 'but got:' portion of the message and correct the input to the '<tenant>/<namespace>' form.
- If the input is a V1 name (three segments), remove the cluster segment: 'tenant/cluster/ns' -> 'tenant/ns'.
- If the input is null, fix the configuration or caller so a real namespace string is supplied.
- If tenant or namespace segments are empty or contain illegal characters, rename them to valid non-empty identifiers.
- Pre-validate with NamespaceName.validateNamespaceName(tenant, namespace) or NamespaceName.isValid(String) before calling get().
Example fix
// before
NamespaceName ns = NamespaceName.get("my-tenant/us-west/my-ns"); // V1
// after
NamespaceName ns = NamespaceName.get("my-tenant/my-ns"); // V2 Defensive patterns
Strategy: try-catch
Validate before calling
if (ns != null && ns.matches("[^/]+/[^/]+")) {
NamespaceName n = NamespaceName.get(ns);
} Type guard
static Optional<NamespaceName> tryParseNamespace(String ns) {
try {
return Optional.of(NamespaceName.get(ns));
} catch (IllegalArgumentException e) {
return Optional.empty();
}
} Try / catch
try {
NamespaceName ns = NamespaceName.get(raw);
} catch (IllegalArgumentException e) {
// message includes 'but got: <input>' plus cause (V1 name, bad chars, null)
throw new ConfigurationException("Namespace must be '<tenant>/<namespace>' (V2). Cause: " + e.getMessage(), e);
} Prevention
- Migrate any remaining V1 'tenant/cluster/namespace' strings to V2 'tenant/namespace'.
- Check the exception cause (getCause()) to distinguish V1-format from character-validation failures.
- Centralize namespace parsing in one utility that logs and wraps this error consistently.
When it happens
Trigger: NamespaceName.get(...) with a null input (NPE at namespace.split), a V1 three-part name 'tenant/cluster/namespace' (the inner V1-not-supported IAE), an invalid tenant/localName rejected by NamedEntity.checkName, or 1/4+ segment names.
Common situations: Upgrading code that still uses V1 namespace names with a cluster component; empty tenant or namespace segments like 'tenant/' or '/default'; illegal characters in tenant or namespace names; null namespace strings from unset configuration.
Related errors
- Invalid namespace format. namespace: ${namespace}
- Invalid namespace format. namespace: %s/%s
- ResourceGroupCreate: Invalid null ResourceGroup config
- ResourceGroupCreate: can't create resource group with an emp
- Invalid key-shared mode: ${keySharedMode}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/abc988635e6112ed.
Report an issue: GitHub.