{"id":"e42e920ba66d37d6","repo":"apache/kafka","slug":"partitions-collection-cannot-be-null","errorCode":null,"errorMessage":"Partitions collection cannot be null","messagePattern":"Partitions collection cannot be null","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java","lineNumber":1212,"sourceCode":"            ));\n        } finally {\n            release();\n        }\n    }\n\n    @Override\n    public void seekToBeginning(Collection<TopicPartition> partitions) {\n        seek(partitions, AutoOffsetResetStrategy.EARLIEST);\n    }\n\n    @Override\n    public void seekToEnd(Collection<TopicPartition> partitions) {\n        seek(partitions, AutoOffsetResetStrategy.LATEST);\n    }\n\n    private void seek(Collection<TopicPartition> partitions, AutoOffsetResetStrategy offsetResetStrategy) {\n        if (partitions == null)\n            throw new IllegalArgumentException(\"Partitions collection cannot be null\");\n\n        acquireAndEnsureOpen();\n        try {\n            applicationEventHandler.addAndGet(new ResetOffsetEvent(\n                partitions,\n                offsetResetStrategy,\n                defaultApiTimeoutDeadlineMs())\n            );\n        } finally {\n            release();\n        }\n    }\n\n    @Override\n    public long position(TopicPartition partition) {\n        return position(partition, defaultApiTimeoutMs);\n    }\n","sourceCodeStart":1194,"sourceCodeEnd":1230,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java#L1194-L1230","documentation":"IllegalArgumentException thrown at the entry of the private seek(Collection<TopicPartition>, AutoOffsetResetStrategy) helper that backs seekToBeginning/seekToEnd when the partitions argument is null. The guard runs before acquireAndEnsureOpen(); passing null is treated as a programming error because ResetOffsetEvent requires a concrete partition set. Note: an empty collection is allowed (the helper will still proceed), only null is rejected.","triggerScenarios":"Calling consumer.seekToBeginning(null) or consumer.seekToEnd(null). Also reachable via a wrapper/utility that passes through a null partition collection when the caller omitted it (e.g. seeking on a null topic partition set computed from an empty request).","commonSituations":"Code computes a partition set from a topic lookup that returned null instead of empty list; refactor that left a default-null parameter; tests calling seekToBeginning(null) by mistake; reactive wrapper that forwards null when upstream emits nothing.","solutions":["Pass a non-null Collection (use Collections.emptyList() if you genuinely have no partitions).","Fix the upstream computation so the partition set is never null — return emptyList() instead.","Add a null-check at the call site and skip the seek call entirely when no partitions are available."],"exampleFix":"// before\nCollection<TopicPartition> parts = lookupPartitions(topic); // may return null\nconsumer.seekToBeginning(parts);\n\n// after\nCollection<TopicPartition> parts = lookupPartitions(topic);\nif (parts == null) parts = List.of();\nif (!parts.isEmpty()) consumer.seekToBeginning(parts);","handlingStrategy":"type-guard","validationCode":"// seekToBeginning/seekToEnd delegate to a private seek(Collection, ...) that\n// rejects null. Validate (and normalize) the collection at the call site.\nstatic java.util.Set<TopicPartition> requirePartitions(Collection<TopicPartition> parts) {\n    if (parts == null)\n        throw new IllegalArgumentException(\"partitions collection must not be null\");\n    // Defensive copy also strips null elements which would otherwise NPE downstream.\n    java.util.Set<TopicPartition> out = new java.util.HashSet<>();\n    for (TopicPartition tp : parts) {\n        if (tp == null) throw new IllegalArgumentException(\"partitions contains a null element\");\n        out.add(tp);\n    }\n    return java.util.Collections.unmodifiableSet(out);\n}\n\n// Usage:\n//   consumer.seekToBeginning(requirePartitions(assigned));\n//   consumer.seekToEnd(requirePartitions(assigned));","typeGuard":"// In Java prefer Collection<TopicPartition> from a trusted source (e.g. consumer.assignment())\n// and wrap external input in a non-null factory (above).\n//\n// TypeScript analogue — make null impossible at the type level:\n//   type TopicPartition = { topic: string; partition: number };\n//   function seekToEnd(c: Consumer, parts: NonEmptyArray<TopicPartition>): void {\n//     // NonEmptyArray< T > = [T, ...T[]] — compiler rejects null/undefined/[]\n//     c.seekToEnd(parts);\n//   }\n//   // Caller must prove non-empty; the function body never sees null.","tryCatchPattern":"// IllegalArgumentException here is purely a null-guard violation; surface it as a\n// programming defect, never swallow.\ntry {\n    consumer.seekToEnd(partitions);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"cannot be null\")) {\n        throw new IllegalStateException(\n            \"Internal error: partitions collection passed to seekToEnd/seekToBeginning was null\", e);\n    }\n    throw e;\n}","preventionTips":["Always source the partitions argument from consumer.assignment() or a typed Set<TopicPartition> you control; avoid ad-hoc List literals built from user input.","Wrap seekToBeginning/seekToEnd in a helper that produces an immutable, null-free set so the contract is enforced once, not at every call site.","Enable static analysis (NullAway, Checker Framework, or IDE null inspections) to flag null collections before runtime.","Treat 'cannot be null' exceptions as bugs in your own wiring, never as recoverable runtime errors."],"tags":["consumer","seek","null-check","validation"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}