{"id":"790dac68ffe4816e","repo":"apache/kafka","slug":"failed-to-construct-kafka-consumer-790dac","errorCode":null,"errorMessage":"Failed to construct kafka consumer","messagePattern":"Failed to construct kafka consumer","errorType":"exception","errorClass":"org.apache.kafka.common.KafkaException","httpStatus":null,"severity":"critical","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java","lineNumber":289,"sourceCode":"                    retryBackoffMs,\n                    retryBackoffMaxMs);\n\n            this.kafkaConsumerMetrics = new KafkaConsumerMetrics(metrics);\n\n            config.logUnused();\n            AppInfoParser.registerAppInfo(CONSUMER_JMX_PREFIX, clientId, metrics, time.milliseconds());\n            log.debug(\"Kafka consumer initialized\");\n        } catch (Throwable t) {\n            // call close methods if internal objects are already constructed; this is to prevent resource leak. see KAFKA-2121\n            // we do not need to call `close` at all when `log` is null, which means no internal objects were initialized.\n            if (this.log != null) {\n                // If a consumer fails during initialization, it means it hasn't joined the group yet.\n                // Since it's not a group member, we use REMAIN_IN_GROUP option when closing\n                // to prevent sending an unnecessary leave request to the coordinator.\n                close(Duration.ZERO, CloseOptions.GroupMembershipOperation.REMAIN_IN_GROUP, true);\n            }\n            // now propagate the exception\n            throw new KafkaException(\"Failed to construct kafka consumer\", t);\n        }\n    }\n\n    // visible for testing\n    ClassicKafkaConsumer(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        this.log = logContext.logger(getClass());\n        this.time = time;\n        this.subscriptions = subscriptions;\n        this.metadata = metadata;\n        this.metrics = new Metrics(time);","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java#L271-L307","documentation":"Thrown by the ClassicKafkaConsumer constructor as a KafkaException wrapping any Throwable raised during initialization. The constructor builds many components (deserializers, metrics, network client, coordinator, fetcher); if any of them throws, the catch-all closes any partially-built internals (see KAFKA-2121) and rethrows under this generic message with the real cause attached. The original exception is always available via getCause().","triggerScenarios":"Any constructor failure: bad deserializer class (ClassNotFoundException/IllegalAccessException); invalid config value (e.g. request.timeout.ms not a positive int); missing or unreachable bootstrap broker during initial metadata fetch triggered at construction; SSL/TLS misconfiguration; SASL JAAS errors; unknown partition.assignment.strategy class name; security.provider failures.","commonSituations":"First-time wiring of a consumer where a class is not on the classpath (custom deserializer, custom assignor); environment differences between dev and prod (TLS truststore path, JAAS config); fat-jar shading stripping broker provider classes; typo in a fully-qualified class name in config; Kerberos/SCRAM credentials not resolvable in the runtime environment.","solutions":["Read the wrapped cause: call exception.getCause() (and getCause().getCause() if needed) to find the real class, config key, or network error.","If the cause is ConfigException, fix the named config property exactly as the message states.","If the cause is a ClassNotFoundException/NoSuchMethodError, fix the classpath/dependency (add the deserializer/assignor module, fix fat-jar shading filters).","If the cause is network-related (ConnectException, SSLHandshakeException, SaslAuthenticationException), validate bootstrap.servers reachability, truststore/keystore paths, and JAAS config from the runtime environment.","Reproduce with a minimal main() using the same properties to isolate framework-induced config mutations."],"exampleFix":"// before\ntry {\n    new KafkaConsumer<>(props);\n} catch (KafkaException e) {\n    log.error(\"consumer init failed\", e);\n}\n\n// after\ntry {\n    new KafkaConsumer<>(props);\n} catch (KafkaException e) {\n    Throwable cause = e.getCause() != null ? e.getCause() : e;\n    log.error(\"consumer init failed: {}\", cause.getMessage(), cause);\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight check of required config keys before construction.\nMap<String,Object> required = Map.of(\n    ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, props.get(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG),\n    ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, props.get(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG),\n    ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, props.get(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG));\nrequired.forEach((k,v) -> {\n    if (v == null) throw new ConfigException(\"Missing required consumer config: \" + k);\n});","typeGuard":null,"tryCatchPattern":"// KafkaException wraps the real cause; inspect getCause().\ntry {\n    consumer = new KafkaConsumer<K,V>(props);\n} catch (KafkaException ke) {\n    Throwable cause = ke.getCause() != null ? ke.getCause() : ke;\n    if (cause instanceof ConfigException || cause instanceof DeserializationException) {\n        log.error(\"Consumer misconfigured; cannot start\", cause);\n        throw new FatalStartupException(cause);\n    }\n    throw ke;\n}","preventionTips":["Always inspect KafkaException.getCause(); the outer message is generic.","Validate Deserializer instances or classes before passing them to the constructor.","Ensure all required keys (bootstrap.servers, key/value.deserializer) are present and non-null in a config loader.","Wrap consumer construction in an application-level factory so failures map to typed startup errors.","Unit-test construction with bad config so the failure mode is known before production."],"tags":["kafka","consumer","classic-consumer","construction","configuration","classpath"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}