{"id":"06d6cd24611ab422","repo":"apache/kafka","slug":"topic-pattern-to-subscribe-to-cannot-be-null-06d6cd","errorCode":null,"errorMessage":"Topic pattern to subscribe to cannot be null","messagePattern":"Topic pattern to subscribe to cannot be null","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java","lineNumber":577,"sourceCode":"     * the max metadata age, the consumer will refresh metadata more often and check for matching topics.\n     * <p>\n     * See {@link #subscribe(Collection, ConsumerRebalanceListener)} for details on the\n     * use of the {@link ConsumerRebalanceListener}. Generally rebalances are triggered when there\n     * is a change to the topics matching the provided pattern and when consumer group membership changes.\n     * Group rebalances only take place during an active call to {@link #poll(Duration)}.\n     *\n     * @param pattern Pattern to subscribe to\n     * @param listener {@link Optional} listener instance to get notifications on partition assignment/revocation\n     *                 for the subscribed topics\n     * @throws IllegalArgumentException If pattern or listener is null\n     * @throws IllegalStateException If {@code subscribe()} is called previously with topics, or assign is called\n     *                               previously (without a subsequent call to {@link #unsubscribe()}), or if not\n     *                               configured at-least one partition assignment strategy\n     */\n    private void subscribeInternal(Pattern pattern, Optional<ConsumerRebalanceListener> listener) {\n        throwIfGroupIdNotDefined();\n        if (pattern == null || pattern.toString().isEmpty())\n            throw new IllegalArgumentException(\"Topic pattern to subscribe to cannot be \" + (pattern == null ?\n                    \"null\" : \"empty\"));\n\n        acquireAndEnsureOpen();\n        try {\n            throwIfNoAssignorsConfigured();\n            log.info(\"Subscribed to pattern: '{}'\", pattern);\n            this.subscriptions.subscribe(pattern, listener);\n            this.coordinator.updatePatternSubscription(metadata.fetch());\n            this.metadata.requestUpdateForNewTopics();\n        } finally {\n            release();\n        }\n    }\n\n    public void unsubscribe() {\n        acquireAndEnsureOpen();\n        try {\n            fetcher.clearBufferedDataForUnassignedPartitions(Collections.emptySet());","sourceCodeStart":559,"sourceCodeEnd":595,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java#L559-L595","documentation":"Thrown by subscribeInternal when the supplied Pattern is null. The classic consumer requires a non-null pattern; a null pattern would otherwise cause an NPE later during periodic metadata matching. The guard sits before subscription state mutation so the consumer remains in a consistent state.","triggerScenarios":"Calling consumer.subscribe((Pattern) null) or consumer.subscribe(null, listener). Passing a field/variable that was never initialized and resolving to null at runtime.","commonSituations":"Loading a topic-filter regex from config/properties where the key is missing and defaults to null. Refactoring that introduces a code path assigning null before subscribe is reached.","solutions":["Pass a non-null java.util.regex.Pattern, e.g. consumer.subscribe(Pattern.compile(System.getProperty(\"topic.filter\", \".*\"))).","Default the pattern from configuration with a fallback so it can never resolve to null.","Add a null check in application code before calling subscribe to surface the misconfiguration with a clearer message."],"exampleFix":"// before\nPattern p = props.containsKey(\"topic.filter\") ? Pattern.compile(props.getProperty(\"topic.filter\")) : null;\nconsumer.subscribe(p);\n\n// after\nPattern p = Pattern.compile(props.getProperty(\"topic.filter\", \".*\"));\nconsumer.subscribe(p);","handlingStrategy":"validation","validationCode":"// Validate pattern before subscribe\njava.util.regex.Pattern pattern = /* ... */;\nif (pattern == null) {\n    throw new IllegalArgumentException(\"Topic pattern to subscribe to cannot be null\");\n}\nconsumer.subscribe(pattern);","typeGuard":"java.util.Objects.requireNonNull(pattern, \"Topic pattern to subscribe to cannot be null\");","tryCatchPattern":"try {\n    consumer.subscribe(pattern);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"null\")) { /* supply a default pattern */ }\n    else throw e;\n}","preventionTips":["Initialize your Pattern constant once at construction rather than passing a computed value that may be null","Use Objects.requireNonNull as a precondition","Treat a null topic pattern as a programming error, not a runtime recovery case"],"tags":["consumer","subscribe","null-argument","validation"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}