provectus/kafka-ui · error · ValidationException

Something went wrong during adding replicas

Error message

Something went wrong during adding replicas

What it means

TopicsService.getPartitionsReassignments builds new partition replica assignments when increasing a topic's replication factor. It greedily appends brokers from the available list to each partition's assignment; if, after the loop, the assignment list is still smaller than the requested total replication factor, the service cannot satisfy the request (not enough eligible brokers) and throws this ValidationException. It is a guard against producing an incomplete reassignment plan.

Solutions

  1. Add more brokers to the cluster or bring offline brokers back so the requested replication factor is satisfiable.
  2. Request a replication factor <= number of healthy brokers.
  3. Verify broker health (GET /api/clusters/{cluster}/brokers) and fix any brokers excluded from assignment.
  4. Check the requested replicationFactorChange payload — ensure totalReplicationFactor is the intended final RF.

Example fix

// before: RF=3 requested on a 2-broker cluster
PATCH /api/clusters/local/topics/orders
{ "totalReplicationFactor": 3 }
// after: request a factor the cluster can satisfy
PATCH /api/clusters/local/topics/orders
{ "totalReplicationFactor": 2 }
Defensive patterns

Strategy: validation

Validate before calling

const brokers = await fetch(`/api/clusters/${cluster}/brokers`).then(r => r.json());
if (targetRF > brokers.length) {
  throw new Error(`Cannot set RF=${targetRF}: cluster has only ${brokers.length} brokers`);
}

Try / catch

try {
  await changeReplicationFactor(cluster, topic, { totalReplicationFactor: rf });
} catch (e) {
  if (e.message.includes('adding replicas')) {
    // insufficient healthy brokers — reduce RF or add brokers
  } else { throw e; }
}

Prevention

When it happens

Trigger: PATCHing a topic's replication factor (POST /api/clusters/{cluster}/topics/{name}/replication-factor or changeReplicationFactor) with a totalReplicationFactor larger than the number of eligible brokers available for assignment, or when the broker pool is exhausted mid-assignment (e.g., brokers offline, filtered out, or already holding constrained placements).

Common situations: Requesting RF=3 on a cluster with only 2 brokers; brokers marked offline/unhealthy are excluded from candidate assignment; topic with partition constraints (leader placement rules) leaving too few candidate brokers; mixed-version clusters where some brokers are excluded from reassignment.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08). Data as JSON: /api/errors/48c315980ca80d17. Report an issue: GitHub.

Appendix: source

Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/TopicsService.java:315

        // Get brokers list sorted by usage
        var brokers = brokersUsage.entrySet().stream()
            .sorted(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .collect(toList());

        // Iterate brokers and try to add them in assignment
        // while partition replicas count != requested replication factor
        for (Integer broker : brokers) {
          if (!assignmentList.contains(broker)) {
            assignmentList.add(broker);
            brokersUsage.merge(broker, 1, Integer::sum);
          }
          if (assignmentList.size() == replicationFactorChange.getTotalReplicationFactor()) {
            break;
          }
        }
        if (assignmentList.size() != replicationFactorChange.getTotalReplicationFactor()) {
          throw new ValidationException("Something went wrong during adding replicas");
        }
      }

      // If we should to decrease Replication factor
    } else if (replicationFactorChange.getTotalReplicationFactor() < currentReplicationFactor) {
      for (Map.Entry<Integer, List<Integer>> assignmentEntry : currentAssignment.entrySet()) {
        var partition = assignmentEntry.getKey();
        var brokers = assignmentEntry.getValue();

        // Get brokers list sorted by usage in reverse order
        var brokersUsageList = brokersUsage.entrySet().stream()
            .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
            .map(Map.Entry::getKey)
            .collect(toList());

        // Iterate brokers and try to remove them from assignment
        // while partition replicas count != requested replication factor
        for (Integer broker : brokersUsageList) {

View on GitHub (pinned to 83b5a60cc0)