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

  1. 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).
  2. If using a custom assignor, package it in the application jar (or an ubershaded jar) so it ships with the consumer.
  3. 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

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


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)