{"id":"8a81e98fe68f1e07","repo":"apache/kafka","slug":"topic-pattern-to-subscribe-to-cannot-be-empty-8a81e9","errorCode":null,"errorMessage":"Topic pattern to subscribe to cannot be empty","messagePattern":"Topic pattern to subscribe to cannot be empty","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 non-null but its toString() is empty (e.g. Pattern.compile(\"\")). An empty pattern matches every topic in the cluster, which is almost never intended and would silently overload the consumer, so the client rejects it up front.","triggerScenarios":"Calling consumer.subscribe(Pattern.compile(\"\")) or passing a Pattern built from an empty string. Loading the regex from an env var or property that resolves to an empty string.","commonSituations":"Configuration placeholder left as empty string (TOPIC_FILTER=). Trailing whitespace stripped to nothing. Wrong default value in a config object.","solutions":["Provide a meaningful regex such as Pattern.compile(\"^events-.*\") instead of an empty string.","Validate configuration at startup and fail loudly when the topic filter is blank.","Default to an explicit catch-all pattern (\".*\") only if consuming every topic is genuinely intended."],"exampleFix":"// before\nString filter = config.get(\"topic.filter\"); // resolves to \"\"\nconsumer.subscribe(Pattern.compile(filter));\n\n// after\nString filter = config.getOrDefault(\"topic.filter\", \"^events-.*\");\nif (filter.isEmpty()) throw new IllegalStateException(\"topic.filter must be set\");\nconsumer.subscribe(Pattern.compile(filter));","handlingStrategy":"validation","validationCode":"java.util.regex.Pattern pattern = /* ... */;\nif (pattern == null || pattern.toString().isEmpty()) {\n    throw new IllegalArgumentException(\"Topic pattern to subscribe to cannot be empty\");\n}\nconsumer.subscribe(pattern);","typeGuard":"// Compile from a non-empty source string so pattern can never be empty\nString src = java.util.Objects.requireNonNull(regexSource);\nif (src.isEmpty()) throw new IllegalArgumentException(\"topic regex source is empty\");\njava.util.regex.Pattern pattern = java.util.regex.Pattern.compile(src);","tryCatchPattern":"try {\n    consumer.subscribe(pattern);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"empty\")) { /* supply a default non-empty pattern */ }\n    else throw e;\n}","preventionTips":["Derive the pattern from a validated, non-empty config string","Reject empty topic-filter config at application startup, not at subscribe time"],"tags":["consumer","subscribe","validation","configuration"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}