{"id":"cc67df331267c219","repo":"apache/kafka","slug":"failed-to-construct-kafka-consumer-cc67df","errorCode":null,"errorMessage":"Failed to construct Kafka consumer","messagePattern":"Failed to construct Kafka consumer","errorType":"exception","errorClass":"KafkaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerDelegateCreator.java","lineNumber":70,"sourceCode":" * not attempt to determine the underlying implementation to avoid coding to an unstable interface. Rather, it is\n * the {@link Consumer} API contract that should serve as the caller's interface.\n */\npublic class ConsumerDelegateCreator {\n\n    public <K, V> ConsumerDelegate<K, V> create(ConsumerConfig config,\n                                                Deserializer<K> keyDeserializer,\n                                                Deserializer<V> valueDeserializer) {\n        try {\n            GroupProtocol groupProtocol = GroupProtocol.valueOf(config.getString(ConsumerConfig.GROUP_PROTOCOL_CONFIG).toUpperCase(Locale.ROOT));\n\n            if (groupProtocol == GroupProtocol.CONSUMER)\n                return new AsyncKafkaConsumer<>(config, keyDeserializer, valueDeserializer, Optional.empty());\n            else\n                return new ClassicKafkaConsumer<>(config, keyDeserializer, valueDeserializer);\n        } catch (KafkaException e) {\n            throw e;\n        } catch (Throwable t) {\n            throw new KafkaException(\"Failed to construct Kafka consumer\", t);\n        }\n    }\n\n    public <K, V> ConsumerDelegate<K, V> create(LogContext logContext,\n                                                Time time,\n                                                ConsumerConfig config,\n                                                Deserializer<K> keyDeserializer,\n                                                Deserializer<V> valueDeserializer,\n                                                KafkaClient client,\n                                                SubscriptionState subscriptions,\n                                                ConsumerMetadata metadata,\n                                                List<ConsumerPartitionAssignor> assignors) {\n        try {\n            GroupProtocol groupProtocol = GroupProtocol.valueOf(config.getString(ConsumerConfig.GROUP_PROTOCOL_CONFIG).toUpperCase(Locale.ROOT));\n\n            if (groupProtocol == GroupProtocol.CONSUMER)\n                return new AsyncKafkaConsumer<>(\n                    logContext,","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerDelegateCreator.java#L52-L88","documentation":"Thrown from the public ConsumerDelegateCreator.create when constructing the chosen consumer delegate (AsyncKafkaConsumer for group.protocol=consumer, or ClassicKafkaConsumer otherwise) raises any Throwable that is not already a KafkaException. KafkaException subclasses are rethrown unchanged (line 67-68) so callers see the original config error; everything else (NullPointerException, IllegalArgumentException, reflective invocation failures, deserializer construction errors) is wrapped in this KafkaException with the original as the cause. This is the top-level failure surfaced from new KafkaConsumer(...).","triggerScenarios":"An application constructs a new KafkaConsumer(Map/Versions props, Deserializer, Deserializer); the resolved group.protocol picks a delegate whose constructor throws a non-Kafka Throwable (bad deserializer with no default ctor, null config value causing NPE, malformed numeric config, missing required property not covered by KafkaException).","commonSituations":"Custom Deserializer/Serializer class without a no-arg constructor (used when only the class name is configured); passing null for a required config key; a property value that fails Number.valueOf or enum parsing outside KafkaException; reflective instantiation of a pluggable class (partition.assignment.strategy, interceptor.classes) failing; providing an invalid group.protocol value that surfaces as a non-Kafka exception.","solutions":["Read KafkaException#getCause to see the real class and message of the underlying failure.","If using custom Deserializers, ensure they have a public no-arg constructor or are passed as instances (not class names).","Validate all config values are non-null and correctly typed before constructing the consumer.","Verify group.protocol is one of the supported values (classic / consumer) and that partition.assignment.strategy / interceptor.classes entries exist on the classpath."],"exampleFix":"// before\nprops.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, MyJsonDeserializer.class.getName());\n// MyJsonDeserializer has no no-arg ctor -> Throwable wrapped here\nnew KafkaConsumer<>(props);\n\n// after\n// give the deserializer a no-arg constructor, OR pass an instance:\nnew KafkaConsumer<>(props, new MyJsonDeserializer(objectMapper), new MyJsonDeserializer(objectMapper));","handlingStrategy":"try-catch","validationCode":"for (String k : java.util.List.of(\"bootstrap.servers\", \"key.deserializer\", \"value.deserializer\")) {\n    if (configs.get(k) == null) {\n        throw new IllegalArgumentException(\"missing required consumer config: \" + k);\n    }\n}\n// also reject unknown config keys via ConsumerConfig.postProcessAndFetchUid();\n// ensure deserializer classes have a public no-arg constructor.","typeGuard":"static boolean isConstructionFailure(Throwable t) {\n    return t instanceof KafkaException\n        && \"Failed to construct Kafka consumer\".equals(t.getMessage());\n}","tryCatchPattern":"try {\n    consumer = new KafkaConsumer<>(configs);\n} catch (KafkaException e) {\n    // e.getCause() holds the real reason (bad deserializer, unknown config, etc.)\n    log.error(\"Consumer construction failed\", e.getCause());\n    throw e;\n}","preventionTips":["Validate the full config map before constructing KafkaConsumer","Ensure key/value deserializers are instantiable (no-arg ctor or fully configured)","Fail fast at startup rather than discovering the error on first poll","Check for unknown or unsupported config keys in the map"],"tags":["kafka","consumer","config","initialization","deserializer"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}