apache/pulsar · error · RestException
Cannot delete the global namespace ${namespaceName}. There a
Error message
Cannot delete the global namespace ${namespaceName}. There are still more than one replication clusters configured. What it means
A 412 PRECONDITION_FAILED thrown by internalDeleteNamespaceBundleAsync when deleting an individual namespace bundle of a global namespace whose policies still have more than one replication cluster, so getClusterThatCanDeleteNamespace() returns null. Bundle deletion, like namespace deletion, requires the namespace to be reduced to a single owning cluster first.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java:575
@SuppressWarnings("deprecation")
protected CompletableFuture<Void> internalDeleteNamespaceBundleAsync(String bundleRange, boolean authoritative,
boolean force) {
log.info()
.attr("namespace", namespaceName)
.attr("bundleRange", bundleRange)
.attr("authoritative", authoritative)
.attr("force", force)
.log("Deleting namespace bundle");
return validateNamespaceOperationAsync(namespaceName, NamespaceOperation.DELETE_BUNDLE)
.thenCompose(__ -> validatePoliciesReadOnlyAccessAsync())
.thenCompose(__ -> getNamespacePoliciesAsync(namespaceName))
.thenCompose(policies -> {
CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
String cluster = policies.getClusterThatCanDeleteNamespace();
if (cluster == null) {
// There are still more than one clusters configured for the global namespace
throw new RestException(Status.PRECONDITION_FAILED, "Cannot delete the global namespace "
+ namespaceName
+ ". There are still more than one replication clusters configured.");
}
if (!cluster.equals(config().getClusterName())) {
// the only replication cluster is other cluster, redirect
future = clusterResources().getClusterAsync(cluster)
.thenCompose(clusterData -> {
if (clusterData.isEmpty()) {
throw new RestException(Status.NOT_FOUND,
"Cluster " + cluster + " does not exist");
}
ClusterData replClusterData = clusterData.get();
URL replClusterUrl;
try {
if (!config().isTlsEnabled() || !isRequestHttps()) {
replClusterUrl = new URL(replClusterData.getServiceUrl());
} else if (StringUtils.isNotBlank(replClusterData.getServiceUrlTls())) {
replClusterUrl = new URL(replClusterData.getServiceUrlTls());View on GitHub (pinned to 820761864e)
Solutions
- Narrow replication clusters to one first (POST .../replication with a single cluster), then delete the bundle.
- Delete the whole namespace with the documented cluster-narrowing flow instead of per-bundle deletes.
- Inspect policies with GET .../replication to confirm the cluster count before bundle operations.
- Ensure the remaining single cluster equals config().getClusterName() to avoid redirect paths.
Example fix
// before curl -X DELETE http://broker:8080/admin/v2/namespaces/t/ns/0x00000000_0xffffffff // 412 // after curl -X POST http://broker:8080/admin/v2/namespaces/t/ns/replication -d '["local"]' curl -X DELETE http://broker:8080/admin/v2/namespaces/t/ns/0x00000000_0xffffffff
Defensive patterns
Strategy: validation
Validate before calling
const clusters = await admin.namespaces().getNamespaceReplicationClusters(tenant, ns);
if (clusters.length !== 1) {
throw new Error(`bundle delete requires single replication cluster; current: ${clusters}`);
} Try / catch
try {
await admin.namespaces().deleteNamespaceBundle(tenant, ns, bundle);
} catch (e) {
if (e.getStatusCode() === 412) {
await admin.namespaces().setNamespaceReplicationClusters(tenant, ns, ['local']);
} else throw e;
} Prevention
- Reduce replication clusters before any bundle-level delete
- Don't use per-bundle deletes as a workaround for namespace cleanup
- Verify cluster count via GET .../replication first
When it happens
Trigger: DELETE /admin/v2/namespaces/{tenant}/{namespace}/{bundle} where the namespace policy's replication_clusters contains 2+ clusters. Also surfaces when operators try to clear bundles one-by-one as a workaround for the namespace-not-empty guard.
Common situations: Geo-replication cleanup scripts that unload/delete bundles before reducing replication clusters; partially drained namespaces where one cluster was removed but others remain; confusion between bundle-level and namespace-level delete requirements.
Related errors
- Cannot delete the global namespace ${nsName}. There are stil
- The replication cluster does not provide TLS encrypted servi
- Cannot delete non empty bundle
- Local cluster is not part of replicate cluster list
- The topic has a max partition index of %d, the number of par
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/6b6853f598509d84.
Report an issue: GitHub.