{"id":"09b229f76ad0ebbb","repo":"apache/kafka","slug":"subscribe-to-re2-j-pattern-is-not-supported-when-u","errorCode":null,"errorMessage":"Subscribe to RE2/J pattern is not supported when usingthe %s protocol defined in config %s","messagePattern":"Subscribe to RE2/J pattern is not supported when usingthe (.+?) protocol defined in config (.+?)","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java","lineNumber":542,"sourceCode":"        }\n    }\n\n    @Override\n    public void subscribe(Pattern pattern, ConsumerRebalanceListener listener) {\n        if (listener == null)\n            throw new IllegalArgumentException(\"RebalanceListener cannot be null\");\n\n        subscribeInternal(pattern, Optional.of(listener));\n    }\n\n    @Override\n    public void subscribe(Pattern pattern) {\n        subscribeInternal(pattern, Optional.empty());\n    }\n\n    @Override\n    public void subscribe(SubscriptionPattern pattern, ConsumerRebalanceListener callback) {\n        throw new UnsupportedOperationException(String.format(\"Subscribe to RE2/J pattern is not supported when using\" +\n            \"the %s protocol defined in config %s\", GroupProtocol.CLASSIC, ConsumerConfig.GROUP_PROTOCOL_CONFIG));\n    }\n\n    @Override\n    public void subscribe(SubscriptionPattern pattern) {\n        throw new UnsupportedOperationException(String.format(\"Subscribe to RE2/J pattern is not supported when using\" +\n            \"the %s protocol defined in config %s\", GroupProtocol.CLASSIC, ConsumerConfig.GROUP_PROTOCOL_CONFIG));\n    }\n\n    /**\n     * Internal helper method for {@link #subscribe(Pattern)} and\n     * {@link #subscribe(Pattern, ConsumerRebalanceListener)}\n     * <p>\n     * Subscribe to all topics matching specified pattern to get dynamically assigned partitions.\n     * The pattern matching will be done periodically against all topics existing at the time of check.\n     * This can be controlled through the {@code metadata.max.age.ms} configuration: by lowering\n     * the max metadata age, the consumer will refresh metadata more often and check for matching topics.\n     * <p>","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java#L524-L560","documentation":"Thrown by ClassicKafkaConsumer.subscribe(SubscriptionPattern, ...) as an UnsupportedOperationException. SubscriptionPattern is the KIP-848 RE2/J-based regex subscription API and is only implemented by the async consumer (group.protocol=consumer). When the classic protocol is selected the method is unsupported by design; the message interpolates GroupProtocol.CLASSIC and ConsumerConfig.GROUP_PROTOCOL_CONFIG so the user knows exactly which config to change. Note the literal source string is missing a space before 'the' ('usingthe'), but the runtime format renders it as-is.","triggerScenarios":"Calling consumer.subscribe(new SubscriptionPattern(\"orders\\\\..*\")) (with or without a callback) on a KafkaConsumer built with group.protocol=classic (the default). Also triggered by frameworks that auto-detect SubscriptionPattern support and call the new API regardless of the configured group protocol.","commonSituations":"Adopting the RE2/J SubscriptionPattern API from examples/docs without also switching group.protocol to consumer; mixed-protocol code paths where some consumers are classic and others async; library code that calls subscribe(SubscriptionPattern) unconditionally; upgrading the client jar and picking up the new API surface before updating config.","solutions":["Set group.protocol=consumer (GroupProtocol.CONSUMER) in the consumer config so the async consumer, which implements SubscriptionPattern, is instantiated.","If you must stay on the classic protocol, use the JDK Pattern overload instead: consumer.subscribe(Pattern.compile(\"orders\\\\..*\"));","Audit framework adapters (Spring Kafka, Kafka Streams wrappers) that may call SubscriptionPattern and ensure they select the consumer protocol when they do.","Update docs/readmes that reference the RE2/J pattern API to also mandate group.protocol=consumer."],"exampleFix":"// before\nprops.put(ConsumerConfig.GROUP_PROTOCOL_CONFIG, \"classic\");\nnew KafkaConsumer<String,String>(props).subscribe(new SubscriptionPattern(\"orders\\\\\\\\..*\"));\n\n// after\nprops.put(ConsumerConfig.GROUP_PROTOCOL_CONFIG, \"consumer\");\nnew KafkaConsumer<String,String>(props).subscribe(new SubscriptionPattern(\"orders\\\\\\\\..*\"));","handlingStrategy":"fallback","validationCode":"// Detect classic protocol at startup and skip the RE2/J SubscriptionPattern API.\nString proto = String.valueOf(props.getOrDefault(\n    ConsumerConfig.GROUP_PROTOCOL_CONFIG, GroupProtocol.CLASSIC.name()));\nboolean isClassic = GroupProtocol.CLASSIC.name().equalsIgnoreCase(proto);\nif (isClassic && pattern instanceof SubscriptionPattern) {\n    throw new UnsupportedOperationException(\n        \"SubscriptionPattern (RE2/J) requires the CONSUMER group protocol; \" +\n        \"use java.util.regex.Pattern with classic consumer, or switch group.protocol.config\");\n}","typeGuard":"// Distinguish the two Pattern types at the call boundary.\nstatic boolean isSubscriptionPatternRe2j(Object p) {\n    return p instanceof org.apache.kafka.clients.consumer.SubscriptionPattern;\n}\n// route:\nif (isSubscriptionPatternRe2j(pattern)) {\n    // only valid on AsyncKafkaConsumer with CONSUMER protocol\n} else {\n    consumer.subscribe((java.util.regex.Pattern) pattern);\n}","tryCatchPattern":"try {\n    consumer.subscribe(subscriptionPattern, callback);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"RE2/J\")) {\n        // Fall back to java.util.regex.Pattern overload on classic consumer.\n        consumer.subscribe(java.util.regex.Pattern.compile(subscriptionPattern.pattern()), callback);\n    } else {\n        throw e;\n    }\n}","preventionTips":["SubscriptionPattern (RE2/J) is only honored on the async consumer with group.protocol=consumer; classic does not support it.","Pick the Pattern overload (java.util.regex) for classic consumers; reserve SubscriptionPattern for the new async API.","Branch your subscribe wrapper on the configured GroupProtocol so the wrong overload is never reached.","Document at the wrapper level which protocol your application uses, so RE2/J misuse fails in review."],"tags":["kafka","consumer","classic-consumer","subscribe","pattern","unsupported-operation","kip-848","group-protocol"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}