apache/kafka · error · KafkaException
is not an instance of…
Error message
{klass} is not an instance of org.apache.kafka.clients.consumer.ConsumerPartitionAssignor What it means
Thrown by ConsumerPartitionAssignor.getAssignorInstances when a class listed in partition.assignment.strategy instantiates successfully but does not implement ConsumerPartitionAssignor. The consumer validates the type before adding the instance, because every assignor must participate in the assign protocol. The message names the offending class so you can find the wrong entry in the config.
Solutions
- Check partition.assignment.strategy and replace the offending FQN with a concrete class implementing ConsumerPartitionAssignor (e.g. org.apache.kafka.clients.consumer.CooperativeStickyAssignor).
- If the class is custom, make it 'implements ConsumerPartitionAssignor' and rebuild; recheck that the interface's methods (assign, name, etc.) are implemented.
- Confirm you are not accidentally listing a base/abstract class or an assignor from a different Kafka module version.
Example fix
// before
props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,
List.of("com.example.MyProducerInterceptor"));
// after
props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,
List.of(CooperativeStickyAssignor.class.getName())); Defensive patterns
Strategy: validation
Validate before calling
for (String fqn : configuredStrategies) {
Class<?> c = Utils.loadClass(fqn, Object.class);
if (!ConsumerPartitionAssignor.class.isAssignableFrom(c))
throw new IllegalArgumentException(fqn + " does not implement ConsumerPartitionAssignor");
} Type guard
static boolean isAssignor(Class<?> c) {
return ConsumerPartitionAssignor.class.isAssignableFrom(c);
} Try / catch
try {
consumer = new KafkaConsumer<>(props);
} catch (KafkaException e) {
if (e.getMessage() != null && e.getMessage().contains("is not an instance of " + ConsumerPartitionAssignor.class.getName())) {
// surface as a configuration error pointing at the offending FQN
}
throw e;
} Prevention
- Prefer referencing built-in assignors by .class.getName() rather than hand-typed strings.
- Add a CI check that loads and type-checks every partition.assignment.strategy entry against ConsumerPartitionAssignor.
- Keep assignor classes in a dedicated package distinct from serializers/interceptors.
When it happens
Trigger: Putting a fully-qualified class name in partition.assignment.strategy that points to a producer interceptor, serializer, or any arbitrary class instead of a ConsumerPartitionAssignor implementation; passing a Class object (rather than a String) that resolves to an unrelated type; refactoring that moved an assignor class but left the old FQN in config.
Common situations: Confusing partition.assignment.strategy with value.deserializer or interceptor.classes config keys; vendoring a class whose package/name is similar to a real assignor; copy-paste from docs that point at an internal abstract class rather than the concrete assignor.
Related errors
- List contains element of type
- The assignor name: ' ' is used in more than one assignor
- ClassNotFoundException exception occurred
- MaxPollRecords must be strictly superior to 0
- Cannot add records for a partition that is not assigned to…
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/230c0aa89e1af3b8.
Report an issue: GitHub.
Appendix: source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java:447
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());
}
} else {
throw new KafkaException("List contains element of type " + klass.getClass().getName() + ", expected String or Class");
}
}
return assignors;
}
}
View on GitHub (pinned to 996fb4585a)