apache/pulsar · error · RestException

Local cluster is not part of replicate cluster list

Error message

Local cluster is not part of replicate cluster list

What it means

This 422 Unprocessable Entity is thrown when updating (increasing) a partitioned topic's partition count and the broker tries to propagate the update to all replication clusters of the topic. The local broker's cluster name is not present in the topic/namespace replication_clusters list, so the local cluster is not entitled to sync partition updates and refuses the operation. Pulsar requires the local cluster to be part of the replication set before performing cluster-wide partitioned-topic updates.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:504

                                    })
                    );
                }).thenCompose(__ -> {
                    if (updateLocal) {
                        return CompletableFuture.completedFuture(null);
                    }
                    // update remote cluster
                    return getReplicationClusters()
                            .thenCompose(replicationClusters -> {
                                if (replicationClusters == null || replicationClusters.isEmpty()) {
                                    return CompletableFuture.completedFuture(null);
                                }
                                boolean containsCurrentCluster =
                                        replicationClusters.contains(pulsar().getConfig().getClusterName());
                                if (!containsCurrentCluster) {
                                    log.error()
                                            .attr("namespace", topicName)
                                            .log("local cluster is not part of replicated cluster for namespace");
                                    throw new RestException(422,
                                            "Local cluster is not part of replicate cluster list");
                                }
                                if (replicationClusters.size() == 1) {
                                    // The replication clusters just has the current cluster itself.
                                    return CompletableFuture.completedFuture(null);
                                }
                                // Do sync operation to other clusters.
                                List<CompletableFuture<Void>> futures = replicationClusters.stream()
                                        .map(replicationCluster -> admin.clusters().getClusterAsync(replicationCluster)
                                                .thenCompose(clusterData -> pulsarService.getBrokerService()
                                                    .getClusterPulsarAdmin(replicationCluster, Optional.of(clusterData))
                                                        .topics().updatePartitionedTopicAsync(topicName.toString(),
                                                            expectPartitions, true, force)
                                                        .exceptionally(ex -> {
                                                            log.warn()
                                                                    .attr("topic", topicName)
                                                                    .attr("replicationCluster", replicationCluster)
                                                                    .exception(ex)

View on GitHub (pinned to 820761864e)

Solutions

  1. Add the local cluster to the replication clusters: run `pulsar-admin namespaces set-replication-clusters <namespace> --clusters <list including local cluster>` (or set topic-level replication clusters with `pulsar-admin topics set-replication-clusters`).
  2. Verify which cluster you are talking to: check `brokerServiceUrl`/`webServiceUrl` of the cluster you administer and confirm pulsar().getConfig().getClusterName() matches a cluster in the replication list.
  3. If the update should stay local, invoke the update with the update-local flag set so remote sync is skipped where the API allows it.
  4. Check for a stale topic-level policy that removed the local cluster and clear it with `pulsar-admin topics remove-replication-clusters`.

Example fix

// before
pulsar-admin namespaces set-replication-clusters my-tenant/my-ns --clusters r1,r2
// after
pulsar-admin namespaces set-replication-clusters my-tenant/my-ns --clusters r1,r2,local-cluster
Defensive patterns

Strategy: validation

Validate before calling

final Set<String> replicationClusters = admin.namespaces().getReplicationClusters(namespace);
final String localCluster = admin.clusters().getCluster(admin.clusters().getClusters().stream()
        .filter(c -> true).findFirst().orElseThrow(), /* use broker config */).getName();
// simpler: read from topic metadata before updating
if (!replicationClusters.contains(localCluster)) {
    throw new IllegalStateException("Add local cluster to replication clusters of " + namespace);
}
admin.topics().updatePartitionedTopicAsync(topic, newPartitions);

Try / catch

try {
    admin.topics().updatePartitionedTopic(topic, partitions);
} catch (PulsarAdminException e) {
    if (e.getStatusCode() == 422) {
        // fix replication clusters then retry
    } else throw e;
}

Prevention

When it happens

Trigger: Calling PUT /admin/v2/persistent/{ns}/{topic}/partitions (update-partitioned-topic / create-partitioned-topic with update-local flag false) on a broker whose cluster is not listed in the namespace's replication_clusters or the topic-level replication_clusters policy.

Common situations: Namespace configured with replication_clusters containing only remote clusters (e.g. clusters r1,r2 while calling the broker on cluster r3); a topic-level replication policy overriding the namespace list and dropping the local cluster; operating against the wrong cluster's broker service URL in a geo-replicated setup.

Related errors


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