{"id":"cff3cef7b9df1504","repo":"apache/kafka","slug":"klass-classnotfoundexception-exception-occurred","errorCode":null,"errorMessage":"{klass} ClassNotFoundException exception occurred","messagePattern":"(.+?) ClassNotFoundException exception occurred","errorType":"exception","errorClass":"KafkaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java","lineNumber":429,"sourceCode":"        }\n    }\n\n    /**\n     * Get a list of configured instances of {@link org.apache.kafka.clients.consumer.ConsumerPartitionAssignor}\n     * based on the class names/types specified by {@link org.apache.kafka.clients.consumer.ConsumerConfig#PARTITION_ASSIGNMENT_STRATEGY_CONFIG}\n     */\n    static List<ConsumerPartitionAssignor> getAssignorInstances(List<String> assignorClasses, Map<String, Object> configs) {\n        List<ConsumerPartitionAssignor> assignors = new ArrayList<>();\n        // a map to store assignor name -> assignor class name\n        Map<String, String> assignorNameMap = new HashMap<>();\n\n        for (Object klass : assignorClasses) {\n            // first try to get the class if passed in as a string\n            if (klass instanceof String) {\n                try {\n                    klass = Utils.loadClass((String) klass, Object.class);\n                } catch (ClassNotFoundException classNotFound) {\n                    throw new KafkaException(klass + \" ClassNotFoundException exception occurred\", classNotFound);\n                }\n            }\n\n            if (klass instanceof Class<?>) {\n                Object assignor = Utils.newInstance((Class<?>) klass);\n                if (assignor instanceof Configurable)\n                    ((Configurable) assignor).configure(configs);\n\n                if (assignor instanceof ConsumerPartitionAssignor) {\n                    String assignorName = ((ConsumerPartitionAssignor) assignor).name();\n                    if (assignorNameMap.containsKey(assignorName)) {\n                        throw new KafkaException(\"The assignor name: '\" + assignorName + \"' is used in more than one assignor: \" +\n                            assignorNameMap.get(assignorName) + \", \" + assignor.getClass().getName());\n                    }\n                    assignorNameMap.put(assignorName, assignor.getClass().getName());\n                    assignors.add((ConsumerPartitionAssignor) assignor);\n                } else {\n                    throw new KafkaException(klass + \" is not an instance of \" + ConsumerPartitionAssignor.class.getName());","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java#L411-L447","documentation":"Thrown by ConsumerPartitionAssignor.getAssignorInstances when Utils.loadClass fails to find the class named in partition.assignment.strategy. The client tries to resolve each configured assignor class name via the context classloader; if the class is absent from the classpath, the ClassNotFoundException is wrapped and rethrown as a KafkaException at consumer construction.","triggerScenarios":"Constructing a KafkaConsumer whose partition.assignment.strategy names a class (fully qualified) that is not on the runtime classpath — e.g. a custom assignor in a jar that was not packaged/deployed, a third-party assignor dependency that was shaded out, or a typo in the class name.","commonSituations":"Using a custom ConsumerPartitionAssignor whose jar is missing from the deployed artifact; fat-jar shading that renames the assignor package without updating the config; typo in the FQCN; referencing a class that exists only in a test source set from production code; deploying a stub config that names an assignor from a different product line.","solutions":["Verify the assignor class name is the correct fully-qualified name and matches what is on the classpath.","Ensure the jar containing the assignor is packaged into the deployed artifact (check the fat-jar / docker image classpath).","If the assignor was removed or renamed, update partition.assignment.strategy to a valid class (e.g. org.apache.kafka.clients.consumer.CooperativeStickyAssignor).","If using a shaded uber-jar, configure the shading plugin to keep the assignor's package, or update the FQCN to the shaded name."],"exampleFix":"// before\nprops.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n    \"com.acme.kafka.CustomAssignor\"); // not on classpath -> throws\n\n// after (option A: ship the jar / fix FQCN)\nprops.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n    \"com.acme.kafka.StickyCustomAssignor\"); // correct FQCN, jar present\n\n// after (option B: fall back to a built-in assignor)\nprops.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n    CooperativeStickyAssignor.class.getName());","handlingStrategy":"validation","validationCode":"// Verify each partition.assignor class is loadable before constructing the consumer:\nList<String> assignors = Arrays.asList(props.getProperty(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, \"\").split(\",\"));\nfor (String name : assignors) {\n    String trimmed = name.trim();\n    if (trimmed.isEmpty()) continue;\n    try {\n        Class<?> cls = Class.forName(trimmed);\n        if (!ConsumerPartitionAssignor.class.isAssignableFrom(cls)) {\n            throw new RuntimeException(trimmed + \" is not a ConsumerPartitionAssignor\");\n        }\n    } catch (ClassNotFoundException e) {\n        throw new RuntimeException(\"partition.assignment.strategy class not on classpath: \" + trimmed, e);\n    }\n}","typeGuard":"static boolean isLoadableAssignor(String className) {\n    try {\n        Class<?> cls = Class.forName(className);\n        return ConsumerPartitionAssignor.class.isAssignableFrom(cls);\n    } catch (ClassNotFoundException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    new KafkaConsumer<>(props);\n} catch (KafkaException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"ClassNotFoundException\")) {\n        // fall back to a default assignor known to be on the classpath\n        props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n                  CooperativeStickyAssignor.class.getName());\n        new KafkaConsumer<>(props);\n    } else throw e;\n}","preventionTips":["Use fully-qualified class names in partition.assignment.strategy (e.g. org.apache.kafka.clients.consumer.CooperativeStickyAssignor).","Ensure any custom assignor JAR is on the consumer's classpath at runtime, not just at compile time.","Validate assignor classes during application bootstrap (Class.forName + isAssignableFrom) so the failure is reported loudly, not on the first poll()."],"tags":["consumer","partition-assignor","classpath","configuration","classloading","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}