apache/kafka · error · KafkaException
ClassNotFoundException exception occurred
Error message
{klass} ClassNotFoundException exception occurred What it means
Thrown by ConsumerPartitionAssignor.getAssignorInstances when a class name listed in partition.assignment.strategy cannot be loaded by Utils.loadClass, raising ClassNotFoundException which is then wrapped in a KafkaException. The consumer cannot start without its assignor(s); the listed class must be on the classpath and accessible.
Solutions
- Verify the class name is correct and the jar is on the runtime classpath (use the built-in org.apache.kafka.clients.consumer.CooperativeStickyAssignor if unsure).
- If using a custom assignor, package it in the application jar (or an ubershaded jar) so it ships with the consumer.
- For framework users (Spring etc.) make sure the dependency is not marked provided/optional.
Example fix
// before
props.put("partition.assignment.strategy",
"com.example.MyCustomAssignor"); // not on classpath
new KafkaConsumer<>(props);
// after
props.put("partition.assignment.strategy",
CooperativeStickyAssignor.class.getName());
new KafkaConsumer<>(props); Defensive patterns
Strategy: try-catch
Validate before calling
for (String name : assignorClassNames) {
try {
Class.forName(name);
} catch (ClassNotFoundException e) {
throw new ConfigException("partition.assignment.strategy class not on classpath: " + name);
}
} Type guard
static boolean isAssignorLoadable(String className) {
try { Class.forName(className); return true; }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
consumer = new KafkaConsumer<>(props);
} catch (KafkaException e) {
if (e.getCause() instanceof ClassNotFoundException) {
throw new ConfigException("Assignor class not on classpath: " + e.getCause().getMessage(), e);
}
throw e;
} Prevention
- Package custom assignors in the application uber-jar; do not mark the dependency 'provided'.
- Use built-in assignors (CooperativeStickyAssignor, StableAssignor) unless a custom one is required.
- Add a startup check that Class.forName succeeds for each configured assignor.
When it happens
Trigger: Setting partition.assignment.strategy to a fully-qualified class name that is not on the consumer's classpath; misspelling the class name; referencing a class in a jar that wasn't packaged with the application.
Common situations: Custom assignor not packaged in the deployed jar/shaded uber-jar; copy-paste of a class name from another project; typo in the FQN; jar present at compile time but excluded at runtime (scope/proguard).
Related errors
- Cannot add records for a partition that is not assigned to…
- Cannot lose partitions that are not currently assigned
- enable.auto.commit cannot be set to true when default group…
- Failed to construct kafka consumer
- cannot be set when group.protocol=
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/cff3cef7b9df1504.
Report an issue: GitHub.
Appendix: source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java:429
}
}
/**
* Get a list of configured instances of {@link org.apache.kafka.clients.consumer.ConsumerPartitionAssignor}
* based on the class names/types specified by {@link org.apache.kafka.clients.consumer.ConsumerConfig#PARTITION_ASSIGNMENT_STRATEGY_CONFIG}
*/
static List<ConsumerPartitionAssignor> getAssignorInstances(List<String> assignorClasses, Map<String, Object> configs) {
List<ConsumerPartitionAssignor> assignors = new ArrayList<>();
// a map to store assignor name -> assignor class name
Map<String, String> assignorNameMap = new HashMap<>();
for (Object klass : assignorClasses) {
// first try to get the class if passed in as a string
if (klass instanceof String) {
try {
klass = Utils.loadClass((String) klass, Object.class);
} catch (ClassNotFoundException classNotFound) {
throw new KafkaException(klass + " ClassNotFoundException exception occurred", classNotFound);
}
}
if (klass instanceof Class<?>) {
Object assignor = Utils.newInstance((Class<?>) klass);
if (assignor instanceof Configurable)
((Configurable) assignor).configure(configs);
if (assignor instanceof ConsumerPartitionAssignor) {
String assignorName = ((ConsumerPartitionAssignor) assignor).name();
if (assignorNameMap.containsKey(assignorName)) {
throw new KafkaException("The assignor name: '" + assignorName + "' is used in more than one assignor: " +
assignorNameMap.get(assignorName) + ", " + assignor.getClass().getName());
}
assignorNameMap.put(assignorName, assignor.getClass().getName());
assignors.add((ConsumerPartitionAssignor) assignor);
} else {
throw new KafkaException(klass + " is not an instance of " + ConsumerPartitionAssignor.class.getName());View on GitHub (pinned to 996fb4585a)