{"record":{"id":"dd04380d03a0988b","repo":"apache/kafka","slug":"cannot-create-a-new-partition-reassignment-without","errorCode":null,"errorMessage":"Cannot create a new partition reassignment without any replicas","messagePattern":"Cannot create a new partition reassignment without any replicas","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/admin/NewPartitionReassignment.java","lineNumber":37,"sourceCode":"\nimport org.apache.kafka.common.annotation.InterfaceAudience;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * A new partition reassignment, which can be applied via {@link AdminClient#alterPartitionReassignments(Map, AlterPartitionReassignmentsOptions)}.\n */\n@InterfaceAudience.Public\npublic class NewPartitionReassignment {\n    private final List<Integer> targetReplicas;\n\n    /**\n     * @throws IllegalArgumentException if no replicas are supplied\n     */\n    public NewPartitionReassignment(List<Integer> targetReplicas) {\n        if (targetReplicas == null || targetReplicas.isEmpty())\n            throw new IllegalArgumentException(\"Cannot create a new partition reassignment without any replicas\");\n        this.targetReplicas = List.copyOf(targetReplicas);\n    }\n\n    public List<Integer> targetReplicas() {\n        return targetReplicas;\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":45,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/clients/src/main/java/org/apache/kafka/clients/admin/NewPartitionReassignment.java#L19-L45","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nNewPartitionReassignment reassignment = new NewPartitionReassignment(newReplicas);\nadmin.alterPartitionReassignments(Map.of(tp, Optional.of(reassignment)));\n\n// after\nif (newReplicas == null || newReplicas.isEmpty()) {\n    throw new IllegalStateException(\"Computed empty replica list for \" + tp);\n}\nNewPartitionReassignment reassignment = new NewPartitionReassignment(newReplicas);","handlingStrategy":"validation","validationCode":"if (targetReplicas == null || targetReplicas.isEmpty()) {\n    throw new IllegalArgumentException(\"targetReplicas must be non-empty for \" + topicPartition);\n}\nNewPartitionReassignment reassignment = new NewPartitionReassignment(targetReplicas);","typeGuard":"// Java has no type-level guard for List non-emptiness; use a helper:\nstatic List<Integer> requireNonEmptyReplicas(List<Integer> replicas) {\n    if (replicas == null || replicas.isEmpty())\n        throw new IllegalArgumentException(\"replicas required\");\n    return replicas;\n}","tryCatchPattern":"try {\n    NewPartitionReassignment r = new NewPartitionReassignment(replicas);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Skipping reassignment for {}: {}\", tp, e.getMessage());\n}","preventionTips":["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."],"tags":["admin-client","partition-reassignment","validation","illegal-argument"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}