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

  1. Before constructing, check the list is non-null and non-empty: `if (replicas == null || replicas.isEmpty()) { /* skip or report */ }`.
  2. Validate the source of your replica plan (reassignment JSON / admin describe output) and reject malformed entries upstream.
  3. 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

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


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)