apache/pulsar · error · RestException
%s's peer-clusters %s can't be part of replication-clusters
Error message
%s's peer-clusters %s can't be part of replication-clusters %s
What it means
Pulsar forbids a cluster's peer-clusters from also appearing in a namespace's replication-clusters, because replication to a peer would loop. The deprecated sync validatePeerClusterConflict computes the intersection of the cluster's peerClusterNames and the requested replicationClusters and throws 409 CONFLICT if any cluster appears in both sets.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java:429
*
* @param clusterName given cluster whose peer-clusters can't be present into replication-cluster list
* @param replicationClusters replication-cluster list
* @deprecated use {@link #validatePeerClusterConflictAsync(String, Set)} instead
*/
@Deprecated
protected void validatePeerClusterConflict(String clusterName, Set<String> replicationClusters) {
try {
ClusterData clusterData = clusterResources().getCluster(clusterName).orElseThrow(
() -> new RestException(Status.PRECONDITION_FAILED, "Invalid replication cluster " + clusterName));
Set<String> peerClusters = clusterData.getPeerClusterNames();
if (peerClusters != null && !peerClusters.isEmpty()) {
Sets.SetView<String> conflictPeerClusters = Sets.intersection(peerClusters, replicationClusters);
if (!conflictPeerClusters.isEmpty()) {
log.warn()
.attr("cluster", clusterName)
.attr("conflictingPeerClusters", conflictPeerClusters)
.log("Peer clusters can't be part of replication clusters");
throw new RestException(Status.CONFLICT,
String.format("%s's peer-clusters %s can't be part of replication-clusters %s", clusterName,
conflictPeerClusters, replicationClusters));
}
}
} catch (RestException re) {
throw re;
} catch (Exception e) {
log.warn()
.attr("cluster", clusterName)
.exception(e)
.log("Failed to get cluster-data");
}
}
protected CompletableFuture<Void> validatePeerClusterConflictAsync(String clusterName,
Set<String> replicationClusters) {
return clusterResources().getClusterAsync(clusterName)
.thenAccept(data -> {View on GitHub (pinned to 820761864e)
Solutions
- Remove the conflicting cluster names from the namespace's replication-clusters list
- Or remove them from the cluster's peerClusterNames (pulsar-admin clusters update) if peer relationships are stale
- Redesign topology: peer-clusters are for local service discovery among clusters sharing a namespace ownership; replication should use only non-peer clusters
- Migrate callers to validatePeerClusterConflictAsync — this sync method is deprecated
Example fix
// before pulsar-admin namespaces set-clusters my-tenant/ns --clusters c1,c2 // c2 is peer of c1's cluster // after: remove the peer conflict pulsar-admin clusters update c1 --peer-cluster-names // then pulsar-admin namespaces set-clusters my-tenant/ns --clusters c1,c2
Defensive patterns
Strategy: validation
Validate before calling
// Reject replication clusters that overlap the cluster's peers, before calling the API
ClusterData cd = admin.clusters().getCluster(clusterName);
Set<String> peers = cd.getPeerClusterNames() == null ? Set.of() : cd.getPeerClusterNames();
Set<String> conflict = new HashSet<>(peers); conflict.retainAll(replicationClusters);
if (!conflict.isEmpty()) throw new IllegalArgumentException("Conflicting peer clusters: " + conflict); Prevention
- Treat peer-clusters and replication-clusters as disjoint sets in your config tooling
- Validate cluster topology in CI before applying admin API changes
- Clean up stale peerClusterNames when decommissioning replication links
When it happens
Trigger: Setting/updating a namespace's replication clusters (namespaces API, setReplicationClusters) or cluster data while the target cluster's ClusterData.peerClusterNames contains one of the requested replication clusters. The offending cluster names are printed in the message.
Common situations: Configuring geo-replication between two clusters that were already declared peers of each other; leftover peerClusterNames from a previous replication topology; automated tooling copying the same set into both peer-clusters and replication-clusters.
Related errors
- Cluster ${cluster} does not exist.
- Local cluster is not part of replicate cluster list
- Timeout during mark-delete operation
- Timeout during clear backlog operation
- Timeout during skip messages operation
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/34ca3b23f0eb2fc7.
Report an issue: GitHub.