{"record":{"id":"eb756a50ef4b0b48","repo":"provectus/kafka-ui","slug":"something-went-wrong-during-removing-replicas","errorCode":null,"errorMessage":"Something went wrong during removing replicas","messagePattern":"Something went wrong during removing replicas","errorType":"validation","errorClass":"ValidationException","httpStatus":400,"severity":"error","filePath":"kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/TopicsService.java","lineNumber":345,"sourceCode":"            .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))\n            .map(Map.Entry::getKey)\n            .collect(toList());\n\n        // Iterate brokers and try to remove them from assignment\n        // while partition replicas count != requested replication factor\n        for (Integer broker : brokersUsageList) {\n          // Check is the broker the leader of partition\n          if (!topic.getPartitions().get(partition).getLeader()\n              .equals(broker)) {\n            brokers.remove(broker);\n            brokersUsage.merge(broker, -1, Integer::sum);\n          }\n          if (brokers.size() == replicationFactorChange.getTotalReplicationFactor()) {\n            break;\n          }\n        }\n        if (brokers.size() != replicationFactorChange.getTotalReplicationFactor()) {\n          throw new ValidationException(\"Something went wrong during removing replicas\");\n        }\n      }\n    } else {\n      throw new ValidationException(\"Replication factor already equals requested\");\n    }\n\n    // Return result map\n    return currentAssignment.entrySet().stream().collect(toMap(\n        e -> new TopicPartition(topic.getName(), e.getKey()),\n        e -> Optional.of(new NewPartitionReassignment(e.getValue()))\n    ));\n  }\n\n  private Map<Integer, List<Integer>> getCurrentAssignment(InternalTopic topic) {\n    return topic.getPartitions().values().stream()\n        .collect(toMap(\n            InternalPartition::getPartition,\n            p -> p.getReplicas().stream()","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/provectus/kafka-ui/blob/83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7/kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/TopicsService.java#L327-L363","documentation":"The mirror of error 38: when decreasing a topic's replication factor, getPartitionsReassignments iterates each partition's current assignment and drops replica entries until only the requested number remain. If the removal loop cannot reduce the broker set to totalReplicationFactor (assignment structure shorter than expected or constrained), it throws this ValidationException rather than emitting an invalid reassignment. The adjacent else-branch also shows RF already equal to the request is rejected separately.","triggerScenarios":"Calling changeReplicationFactor (POST /api/clusters/{cluster}/topics/{name}/replication-factor) with totalReplicationFactor lower than the current RF while the algorithm cannot shrink the current assignments down to the target count — e.g., current assignment lists that don't contain enough removable entries under the constraints applied while selecting brokers to keep.","commonSituations":"Reducing RF on a topic whose partitions were previously manually reassigned with custom replica layouts; target RF equals or exceeds some partitions' current assignable broker set; requesting the same RF as current (which instead yields 'Replication factor already equals requested'); conflating replication-factor change with partition-count change.","solutions":["Verify the requested totalReplicationFactor is strictly less than the topic's current replication factor and >= 1.","Inspect the topic's current assignments (kafka-topics --describe) for unusual layouts; normalize them first or reassign manually with kafka-reassign-partitions.","If Kafka version supports it, note that decreasing RF via reassignment may be restricted — remove replicas manually via a reassignment JSON.","Ensure the topic isn't in the middle of another reassignment that altered assignments unexpectedly."],"exampleFix":"// before: reducing RF to 2 while a partition assignment is malformed/unexpected\nPOST /api/clusters/local/topics/orders/replication-factor\n{ \"totalReplicationFactor\": 2 }  // fails building reassignment\n// after: normalize assignments via manual reassignment first\n{\"version\":1,\"partitions\":[{\"topic\":\"orders\",\"partition\":0,\"replicas\":[1,2,3]}]}\n// then request RF decrease","handlingStrategy":"validation","validationCode":"const topic = await fetch(`/api/clusters/${cluster}/topics/${name}`).then(r => r.json());\nconst currentRF = Math.max(...topic.partitionReplications || [1]);\nif (targetRF >= currentRF) {\n  throw new Error(`Target RF ${targetRF} must be lower than current RF ${currentRF}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await changeReplicationFactor(cluster, topic, { totalReplicationFactor: rf });\n} catch (e) {\n  if (e.message.includes('removing replicas') || e.message.includes('already equals')) {\n    // reassign partitions manually or skip — RF change not applicable\n  } else { throw e; }\n}","preventionTips":["Read the topic's current replication factor before requesting a decrease.","Avoid decreasing RF on topics with custom/manual replica assignments; use kafka-reassign-partitions instead.","Remember kafka-ui can raise RF automatically but lowering RF may need a manual reassignment plan depending on Kafka version."],"tags":["kafka","replication-factor","topic-reassignment","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7","analyzedAt":"2026-09-08T04:35:39.002Z","contentChangedAt":"2026-09-08T04:35:39.002Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}