{"id":"1148b6cd4ae08000","repo":"apache/kafka","slug":"topic-partitions-to-assign-to-cannot-have-null-or-1148b6","errorCode":null,"errorMessage":"Topic partitions to assign to cannot have null or empty topic","messagePattern":"Topic partitions to assign to cannot have null or empty topic","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java","lineNumber":619,"sourceCode":"            log.info(\"Unsubscribed all topics or patterns and assigned partitions\");\n        } finally {\n            release();\n        }\n    }\n\n    @Override\n    public void assign(Collection<TopicPartition> partitions) {\n        acquireAndEnsureOpen();\n        try {\n            if (partitions == null) {\n                throw new IllegalArgumentException(\"Topic partition collection to assign to cannot be null\");\n            } else if (partitions.isEmpty()) {\n                this.unsubscribe();\n            } else {\n                for (TopicPartition tp : partitions) {\n                    String topic = (tp != null) ? tp.topic() : null;\n                    if (isBlank(topic))\n                        throw new IllegalArgumentException(\"Topic partitions to assign to cannot have null or empty topic\");\n                }\n                fetcher.clearBufferedDataForUnassignedPartitions(partitions);\n\n                // make sure the offsets of topic partitions the consumer is unsubscribing from\n                // are committed since there will be no following rebalance\n                if (coordinator != null)\n                    this.coordinator.maybeAutoCommitOffsetsAsync(time.milliseconds());\n\n                log.info(\"Assigned to partition(s): {}\", partitions.stream().map(TopicPartition::toString).collect(Collectors.joining(\", \")));\n                if (this.subscriptions.assignFromUser(new HashSet<>(partitions)))\n                    metadata.requestUpdateForNewTopics();\n            }\n        } finally {\n            release();\n        }\n    }\n\n    @Override","sourceCodeStart":601,"sourceCodeEnd":637,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java#L601-L637","documentation":"Thrown by assign(Collection<TopicPartition>) when iterating the partitions collection encounters a TopicPartition that is itself null or whose topic() returns a blank string (checked via isBlank). The client cannot route fetches without a concrete topic name, so it refuses the assignment.","triggerScenarios":"Passing a collection containing a null element (e.g. a List with nulls), or constructing TopicPartition(\"\", 0) / TopicPartition(null, 0). Stream pipelines that filter into a list leaving null placeholders.","commonSituations":"Parsing topic names from an external source where some entries are blank. Off-by-one when building partitions from a partition count. Using a map keyed by topic where a key was deleted.","solutions":["Filter out null and blank-topic partitions before assign: partitions.removeIf(tp -> tp == null || isBlank(tp.topic())).","Validate topic names at construction time so TopicPartition is never built with a blank topic.","Log skipped entries during partition resolution so misconfiguration is visible."],"exampleFix":"// before\nList<TopicPartition> parts = topics.stream()\n    .map(t -> t == null ? null : new TopicPartition(t, 0))\n    .collect(Collectors.toList());\nconsumer.assign(parts);\n\n// after\nList<TopicPartition> parts = topics.stream()\n    .filter(Objects::nonNull)\n    .filter(t -> !t.trim().isEmpty())\n    .map(t -> new TopicPartition(t, 0))\n    .collect(Collectors.toList());\nconsumer.assign(parts);","handlingStrategy":"validation","validationCode":"java.util.Collection<org.apache.kafka.common.TopicPartition> partitions = /* ... */;\nfor (org.apache.kafka.common.TopicPartition tp : partitions) {\n    if (tp == null || tp.topic() == null || tp.topic().trim().isEmpty()) {\n        throw new IllegalArgumentException(\"Topic partitions to assign to cannot have null or empty topic\");\n    }\n}\nconsumer.assign(partitions);","typeGuard":"static boolean isValidTopicPartition(org.apache.kafka.common.TopicPartition tp) {\n    return tp != null && tp.topic() != null && !tp.topic().trim().isEmpty()\n        && tp.partition() >= 0;\n}\n\nboolean allValid = partitions.stream().allMatch(YourClass::isValidTopicPartition);","tryCatchPattern":"try {\n    consumer.assign(partitions);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"null or empty topic\")) {\n        partitions = partitions.stream()\n            .filter(tp -> tp != null && tp.topic() != null && !tp.topic().isEmpty())\n            .collect(java.util.stream.Collectors.toList());\n        consumer.assign(partitions);\n    } else throw e;\n}","preventionTips":["Construct TopicPartition objects from validated topic names only","Filter out nulls/sentinels before assigning","Reject blank topic names at config-load time"],"tags":["consumer","assign","validation","topic-partition"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}