apache/pulsar · error · RestException

Cluster [${clusterId}] is not in the list of allowed cluster

Error message

Cluster [${clusterId}] is not in the list of allowed clusters list for namespace [${namespaceName}]

What it means

HTTP 400 (BAD_REQUEST) returned by the set-replication-clusters API when a requested cluster is not part of the namespace's allowed-cluster list — Policies.checkNewReplicationClusters fails because the namespace's is_allow_auto_update or allowed_clusters policy does not include the target cluster. This is a tenant/namespace policy restriction, not a cluster-registration problem.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java:877

                    return Sets.newHashSet(clusterIds);
                }).thenCompose(replicationClusterSet -> clustersAsync()
                        .thenCompose(clusters -> {
                            List<CompletableFuture<Void>> futures =
                                    replicationClusterSet.stream().map(clusterId -> {
                                        if (!clusters.contains(clusterId)) {
                                            throw new RestException(Status.FORBIDDEN,
                                                    "Invalid cluster id: " + clusterId);
                                        }
                                        return validatePeerClusterConflictAsync(clusterId, replicationClusterSet)
                                            .thenCompose(__ -> getNamespacePoliciesAsync(this.namespaceName)
                                                .thenCompose(nsPolicies -> {
                                                    if (!Policies.checkNewReplicationClusters(nsPolicies,
                                                            replicationClusterSet)) {
                                                        String msg = String.format("Cluster [%s] is not in the "
                                                                + "list of allowed clusters list for namespace "
                                                                + "[%s]", clusterId, namespaceName.toString());
                                                        log.info(msg);
                                                        throw new RestException(Status.BAD_REQUEST, msg);
                                                    }
                                                    return validateClusterForTenantAsync(
                                                            namespaceName.getTenant(), clusterId);
                                                }));
                                    }).collect(Collectors.toList());
                            return FutureUtil.waitForAll(futures).thenApply(__ -> replicationClusterSet);
                        }))
                .thenCompose(replicationClusterSet -> {
                    if (!compareTopicPartitions) {
                        return CompletableFuture.completedFuture(replicationClusterSet);
                    }
                    return getNamespacePoliciesAsync(namespaceName)
                        .thenCompose(policies ->
                            validateReplicationClusterCompatibility(replicationClusterSet,
                            policies.replication_clusters))
                        .thenApply(__ -> replicationClusterSet);
                }).thenCompose(replicationClusterSet -> updatePoliciesAsync(namespaceName, policies -> {
                    policies.replication_clusters = replicationClusterSet;

View on GitHub (pinned to 820761864e)

Solutions

  1. Inspect namespace policy (GET /namespaces/{ns}) and add the cluster to the allowed clusters list first (POST .../replication or the cluster-allowed API).
  2. Pick a different cluster that is already in the namespace's allowed list.
  3. Update tenant-level allowed-cluster policy if the namespace policy inherits it.
  4. Align your deployment tooling with the namespace's allowedClusters setting before emitting replication changes.

Example fix

// before
setReplicationClusters(ns, List.of("cluster-c")); // not in allowed list
// after
admin.namespaces().setNamespaceReplicationClusters(ns, List.of("cluster-c")); // first allow it
setReplicationClusters(ns, List.of("cluster-c"));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> allowed = new HashSet<>(admin.namespaces().getNamespaceReplicationClusters(ns));
// and tenant-level allowed clusters:
Set<String> tenantAllowed = admin.tenants().getTenantInfo(tenant).getAllowedClusters();
List<String> disallowed = clusterIds.stream().filter(c -> !tenantAllowed.contains(c)).toList();
if (!disallowed.isEmpty()) throw new IllegalArgumentException("Clusters not allowed for tenant: " + disallowed);

Try / catch

try {
    admin.namespaces().setNamespaceReplicationClusters(ns, clusterIds);
} catch (PulsarAdminException.BadRequestException e) {
    // cluster not in allowed list — update policy or choose another cluster
}

Prevention

When it happens

Trigger: POST /namespaces/{tenant}/{namespace}/replication where a clusterId passes cluster registration but is absent from nsPolicies.replication_clusters / allowed cluster list enforced by checkNewReplicationClusters in internalSetNamespaceReplicationClusters.

Common situations: Tenant geo-restriction policies blocking clusters outside an approved set; namespace created with allowed_clusters that was later narrowed; operator assumes any registered cluster is usable; policy updated by governance automation between operations.

Related errors


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