apache/pulsar · error · RestException
Broker doesn't allow forced deletion of namespaces
Error message
Broker doesn't allow forced deletion of namespaces
What it means
A 405 METHOD_NOT_ALLOWED thrown during precheckWhenDeleteNamespace when a namespace delete is requested with force=true but the broker's isForceDeleteNamespaceAllowed configuration is false (the default). The broker intentionally refuses force deletion of namespaces as a data-safety guard; callers must either disable forcing or enable the broker-level allowance.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java:480
log.error()
.exception(ex)
.log("Get admin client error when preparing to delete topics.");
return FutureUtil.failedFuture(ex);
}
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (String topicName : topicNames) {
futures.add(admin.topics().deleteAsync(topicName, true));
}
return FutureUtil.waitForAll(futures);
}
private CompletableFuture<Policies> precheckWhenDeleteNamespace(NamespaceName nsName, boolean force) {
CompletableFuture<Policies> preconditionCheck =
validateTenantOperationAsync(nsName.getTenant(), TenantOperation.DELETE_NAMESPACE)
.thenCompose(__ -> validatePoliciesReadOnlyAccessAsync())
.thenCompose(__ -> {
if (force && !pulsar().getConfiguration().isForceDeleteNamespaceAllowed()) {
throw new RestException(Status.METHOD_NOT_ALLOWED,
"Broker doesn't allow forced deletion of namespaces");
}
return CompletableFuture.completedFuture(null);
})
.thenCompose(__ -> namespaceResources().getPoliciesAsync(nsName))
.thenCompose(policiesOpt -> {
if (policiesOpt.isEmpty()) {
throw new RestException(Status.NOT_FOUND, "Namespace " + nsName + " does not exist.");
}
Policies policies = policiesOpt.get();
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 " + nsName + ". There are still more than "
+ "one replication clusters configured or replication clusters is empty.");
}
if (!cluster.equals(config().getClusterName())) {View on GitHub (pinned to 820761864e)
Solutions
- Set forceDeleteNamespaceAllowed=true in broker.conf / the broker.conf of the target cluster if force deletion is intended policy.
- Remove force=true from the delete request and delete topics explicitly first (safer).
- Apply the config via broker admin/configmanager endpoint or Helm values if running on Kubernetes, then retry.
- Verify which cluster you are hitting — a redirect to another cluster may surface a broker with a different force-delete policy.
Example fix
# before (broker.conf) forceDeleteNamespaceAllowed=false # after forceDeleteNamespaceAllowed=true # then retry: curl -X DELETE 'http://broker:8080/admin/v2/namespaces/my-tenant/my-ns?force=true'
Defensive patterns
Strategy: validation
Validate before calling
// check broker policy before sending force delete
const ok = await fetch(`${baseUrl}/admin/v2/broker-runtime`);
// or simply omit force unless you've confirmed forceDeleteNamespaceAllowed=true in broker.conf Try / catch
try {
await admin.namespaces().deleteNamespace(tenant, ns, true);
} catch (e) {
if (e.getStatusCode() === 405) {
// fall back to non-forced deletion after draining topics
} else throw e;
} Prevention
- Confirm forceDeleteNamespaceAllowed=true before using force=true
- Prefer explicit topic deletion over force delete
- Align this config across dev/prod clusters to avoid script drift
When it happens
Trigger: Calling DELETE /admin/v2/namespaces/{tenant}/{namespace}?force=true while pulsar.broker.forceDeleteNamespaceAllowed=false on the target broker. The check runs after tenant DELETE_NAMESPACE authorization and policies read-only validation, before any topics are inspected.
Common situations: Operators scripting namespace teardown with force=true on a default-configured broker; cluster-to-cluster config drift where dev brokers allow force delete but prod does not; upgrading Pulsar where the guard default was changed/adopted.
Related errors
- Cannot delete non empty namespace
- Cannot delete the global namespace ${nsName}. There are stil
- Local cluster is not part of replicate cluster list
- Entry filter '${filterName}' not found
- No entry filter is found for name `${filterName}`. Available
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/c8ecf543647b68b7.
Report an issue: GitHub.