apache/kafka · error · KafkaException
klass is not an instance of t.getName()
Error message
klass is not an instance of t.getName()
What it means
KafkaException thrown by getConfiguredInstance after successfully instantiating a class when the resulting object is not an instance of the expected super-type T (i.e. t.isInstance(o) is false). The expected interface name (t.getName()) and the class are both in the message. It is a type-assignment guard: the configured class loaded fine but does not implement/extend the interface Kafka requires for that slot (e.g. Partitioner, Serializer, Converter, Transform, ConfigProvider, MetricsReporter).
Source
Thrown at clients/src/main/java/org/apache/kafka/common/config/AbstractConfig.java:416
private <T> T getConfiguredInstance(Object klass, Class<T> t, Map<String, Object> configPairs) {
if (klass == null)
return null;
Object o;
if (klass instanceof String) {
try {
o = Utils.newInstance((String) klass, t);
} catch (ClassNotFoundException e) {
throw new KafkaException("Class " + klass + " cannot be found", e);
}
} else if (klass instanceof Class<?>) {
o = Utils.newInstance((Class<?>) klass);
} else
throw new KafkaException("Unexpected element of type " + klass.getClass().getName() + ", expected String or Class");
try {
if (!t.isInstance(o))
throw new KafkaException(klass + " is not an instance of " + t.getName());
if (o instanceof Configurable)
((Configurable) o).configure(configPairs);
} catch (Exception e) {
maybeClose(o, "AutoCloseable object constructed and configured during failed call to getConfiguredInstance");
throw e;
}
return t.cast(o);
}
/**
* Get a configured instance of the give class specified by the given configuration key. If the object implements
* Configurable configure it using the configuration.
*
* @param key The configuration key for the class
* @param t The interface the class should implement
* @return A configured instance of the class
*/
public <T> T getConfiguredInstance(String key, Class<T> t) {View on GitHub (pinned to c31c9215e1)
Solutions
- Confirm the configured class implements the required interface named in the message (Serializer, Deserializer, Partitioner, Converter, Transformation, ConfigProvider, MetricsReporter, etc.).
- Check the fully-qualified name: a same-named class in the wrong package is a frequent cause.
- If you wrote the class, add `implements <expected-interface>` and implement its methods.
- Align versions: if the interface changed across Kafka versions, rebuild/upgrade the plugin against the matching kafka-clients version.
Example fix
// before: configured class does not implement Serializer
public class MyJsonEncoder { /* encodes but is not a Serializer */ }
props.put("value.serializer", "com.example.MyJsonEncoder");
// after
public class MyJsonEncoder implements org.apache.kafka.common.serialization.Serializer<MyType> {
@Override public byte[] serialize(String topic, MyType data) { /* ... */ return null; }
}
props.put("value.serializer", "com.example.MyJsonEncoder"); Defensive patterns
Strategy: validation
Validate before calling
// Verify the class is assignable to the expected interface before asking Kafka to build it.
String className = String.valueOf(config.get(key));
Class<?> candidate = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
if (!expectedInterface.isAssignableFrom(candidate)) {
throw new IllegalArgumentException(
className + " does not implement " + expectedInterface.getName());
}
T plugin = config.getConfiguredInstance(key, expectedInterface); Type guard
boolean implementsT(Class<?> candidate, Class<?> t) {
return candidate != null && t.isAssignableFrom(candidate);
} Try / catch
try {
T plugin = config.getConfiguredInstance(key, T.class);
} catch (org.apache.kafka.common.KafkaException ke) {
if (ke.getMessage().contains("is not an instance of")) {
// right class name, wrong interface — e.g. a Serializer used where Deserializer was required
log.error("Plugin '{}' does not implement the required interface", config.get(key));
} else {
throw ke;
}
} Prevention
- Common cause: pairing a class with the wrong role (Serializer vs Deserializer, Partitioner vs ProducerInterceptor).
- Keep one ConfigDef entry per role; don't reuse a key for multiple plugin types.
- Add a unit test that loads each configured class and asserts isAssignableFrom against its expected interface.
When it happens
Trigger: A config key requiring a specific interface is pointed at a class that exists on the classpath but does not implement it: e.g. setting key.serializer to a class that does not implement org.apache.kafka.common.serialization.Serializer, or a Connect transform class that does not implement Transformation. The class instantiates via its no-arg/default constructor, then the isInstance check fails.
Common situations: See trigger scenarios.
Related errors
- Class klass cannot be found
- Unknown configuration '%s'
- Non-string value found in original settings for key entry.ge
- Unexpected element of type klass.getClass().getName(), expec
- {klass} ClassNotFoundException exception occurred
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/518b97522e02e1aa.json.
Report an issue: GitHub.