apache/pulsar · error · IllegalArgumentException
V1 namespace names (with cluster component) are no longer su
Error message
V1 namespace names (with cluster component) are no longer supported. Please use the V2 format: '<tenant>/<namespace>'. Got: ${namespace} What it means
The NamespaceName constructor parses 'tenant/namespace' strings. A three-part name (cluster/tenant/namespace — the legacy V1 format) is explicitly rejected because V1 namespaces with a cluster component are no longer supported; callers must use the V2 'tenant/namespace' format.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/naming/NamespaceName.java:100
}
return Optional.of(get(namespace));
}
@SuppressFBWarnings("DCN_NULLPOINTER_EXCEPTION")
private NamespaceName(String namespace) {
// 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() {View on GitHub (pinned to 820761864e)
Solutions
- Strip the leading cluster segment and use the V2 format '<tenant>/<namespace>'
- Update legacy topic/namespace URLs and configuration to drop the cluster component
- Create the namespace under the V2 scheme (without cluster) if it does not exist yet
Example fix
// before
NamespaceName ns = NamespaceName.get("cluster-a/tenant1/app1"); // V1
// after
NamespaceName ns = NamespaceName.get("tenant1/app1"); // V2, cluster segment removed Defensive patterns
Strategy: validation
Validate before calling
String[] parts = namespace.split("/");
if (parts.length == 3) {
// legacy V1 with cluster segment — normalize to V2
namespace = parts[1] + "/" + parts[2];
}
if (namespace.split("/").length != 2) {
throw new IllegalArgumentException("Namespace must be V2 '<tenant>/<namespace>': " + namespace);
} Type guard
boolean isV2Namespace(String ns) {
String[] p = ns == null ? new String[0] : ns.split("/");
return p.length == 2 && !p[0].isEmpty() && !p[1].isEmpty();
} Try / catch
try {
NamespaceName ns = NamespaceName.get(namespace);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("V1 namespace names")) {
String[] p = namespace.split("/");
NamespaceName ns = NamespaceName.get(p[p.length - 2] + "/" + p[p.length - 1]);
} else {
throw e;
}
} Prevention
- Normalize legacy V1 cluster/tenant/namespace strings at config/URL ingestion time
- Search your codebase and configs for three-segment namespace patterns
- Document that cluster is encoded in serviceUrl, not in namespace names, for V2
When it happens
Trigger: Passing a V1-style namespace such as 'use-my-cluster/my-tenant/my-ns' to NamespaceName.get/constructor, or consuming legacy configuration/URLs that still contain the cluster segment.
Common situations: Migrating from old Pulsar clusters where topic URLs embed the cluster name, copied legacy configs, bookmarks/scripts generating old-style namespace strings.
Related errors
- Invalid null namespace: ${namespace}
- Namespace name is not valid
- Tenant name or namespace is not valid
- Invalid named entity: ${name}
- Invalid namespace format. expected <tenant>/<namespace> but
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/7e2d77be4233e1b7.
Report an issue: GitHub.