apache/kafka · error · IllegalArgumentException
Cannot create a new partition reassignment without any…
Error message
Cannot create a new partition reassignment without any replicas
What it means
Thrown by the NewPartitionReassignment constructor when targetReplicas is null or empty. This value object represents the desired replica list for a partition being reassigned via AdminClient.alterPartitionReassignments. Kafka rejects a reassignment plan with zero replicas because a partition must always have at least one in-sync replica to remain available.
Solutions
- Before constructing, check the list is non-null and non-empty: `if (replicas == null || replicas.isEmpty()) { /* skip or report */ }`.
- Validate the source of your replica plan (reassignment JSON / admin describe output) and reject malformed entries upstream.
- If computing replicas programmatically, fall back to the current partition's replicas when the new set would be empty.
Example fix
// before
NewPartitionReassignment reassignment = new NewPartitionReassignment(newReplicas);
admin.alterPartitionReassignments(Map.of(tp, Optional.of(reassignment)));
// after
if (newReplicas == null || newReplicas.isEmpty()) {
throw new IllegalStateException("Computed empty replica list for " + tp);
}
NewPartitionReassignment reassignment = new NewPartitionReassignment(newReplicas); Defensive patterns
Strategy: validation
Validate before calling
if (targetReplicas == null || targetReplicas.isEmpty()) {
throw new IllegalArgumentException("targetReplicas must be non-empty for " + topicPartition);
}
NewPartitionReassignment reassignment = new NewPartitionReassignment(targetReplicas); Type guard
// Java has no type-level guard for List non-emptiness; use a helper:
static List<Integer> requireNonEmptyReplicas(List<Integer> replicas) {
if (replicas == null || replicas.isEmpty())
throw new IllegalArgumentException("replicas required");
return replicas;
} Try / catch
try {
NewPartitionReassignment r = new NewPartitionReassignment(replicas);
} catch (IllegalArgumentException e) {
log.warn("Skipping reassignment for {}: {}", tp, e.getMessage());
} Prevention
- Validate computed replica lists at the algorithm boundary, not at construction.
- Treat an empty result from rack-aware/balancing logic as an explicit error to handle, not as 'no change'.
- Unit-test your reassignment plan builder with edge cases: empty input, single broker, all-excluded.
When it happens
Trigger: Calling `new NewPartitionReassignment(null)` or `new NewPartitionReassignment(Collections.emptyList())`, then passing the result to Admin.alterPartitionReassignments. Also triggered when a computed replica list (e.g. from a rack-aware algorithm or JSON plan parser) collapses to empty due to filtering.
Common situations: Loading a reassignment JSON file whose 'replicas' field is missing or empty; building the list dynamically and an upstream filter (e.g. exclude brokers in maintenance) removes every entry; passing null accidentally from a Optional.orElse(null) chain.
Related errors
- Empty string is not allowed.
- Expected 0 <= minVersion <= maxVersion but received…
- Invalid empty members has been provided
- Leading or trailing whitespace is not allowed.
- Null argument not allowed.
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/dd04380d03a0988b.
Report an issue: GitHub.
Appendix: source
Thrown at clients/src/main/java/org/apache/kafka/clients/admin/NewPartitionReassignment.java:37
import org.apache.kafka.common.annotation.InterfaceAudience;
import java.util.List;
import java.util.Map;
/**
* A new partition reassignment, which can be applied via {@link AdminClient#alterPartitionReassignments(Map, AlterPartitionReassignmentsOptions)}.
*/
@InterfaceAudience.Public
public class NewPartitionReassignment {
private final List<Integer> targetReplicas;
/**
* @throws IllegalArgumentException if no replicas are supplied
*/
public NewPartitionReassignment(List<Integer> targetReplicas) {
if (targetReplicas == null || targetReplicas.isEmpty())
throw new IllegalArgumentException("Cannot create a new partition reassignment without any replicas");
this.targetReplicas = List.copyOf(targetReplicas);
}
public List<Integer> targetReplicas() {
return targetReplicas;
}
}
View on GitHub (pinned to 996fb4585a)