apache/kafka · error · ConfigException

Expected a Class instance or class name.

Error message

Expected a Class instance or class name.

What it means

Thrown by the Type.CLASS branch of ConfigDef.parseType when the value is neither a java.lang.Class nor a String. CLASS-typed configs (e.g. partitioner.class, key.serializer, value.deserializer, metric.reporters entries, client.dns.lookup via older paths, security.providers) are accepted as an actual Class object or as a fully-qualified class name string loaded via Utils.loadClass. Any other type (instance object, Map, Number) is rejected so that class loading is never attempted on garbage input.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java:784

                    else
                        throw new ConfigException(name, value, "Expected value to be a double, but it was a " + value.getClass().getName());
                case LIST:
                    if (value instanceof List)
                        return value;
                    else if (value instanceof String)
                        if (trimmed.isEmpty())
                            return List.of();
                        else
                            return Arrays.asList(COMMA_WITH_WHITESPACE.split(trimmed, -1));
                    else
                        throw new ConfigException(name, value, "Expected a comma separated list.");
                case CLASS:
                    if (value instanceof Class)
                        return value;
                    else if (value instanceof String) {
                        return Utils.loadClass(trimmed, Object.class);
                    } else
                        throw new ConfigException(name, value, "Expected a Class instance or class name.");
                default:
                    throw new IllegalStateException("Unknown type.");
            }
        } catch (NumberFormatException e) {
            throw new ConfigException(name, value, "Not a number of type " + type);
        } catch (ClassNotFoundException e) {
            throw new ConfigException(name, value, "Class " + value + " could not be found.");
        }
    }

    /**
     * Convert the provided object into a string based on its type.
     * <p>
     * This method uses Java's {@link #toString()} for {@link Type#BOOLEAN}, {@link Type#SHORT}, {@link Type#INT},
     * {@link Type#LONG}, {@link Type#DOUBLE}, {@link Type#STRING} and {@link Type#PASSWORD} objects.
     * For {@link Type#LIST} objects, Java's {@link #toString()} is used for each entry and entries are concatenated
     * separated by commas. For {@link Type#CLASS} objects, {@link Class#getName()} is used.
     * @param parsedValue The object to convert into a string

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Set the property to the fully-qualified class name string (e.g. props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, MySerializer.class.getName())).
  2. Or set it to a Class<?> object (e.g. props.put(..., MySerializer.class)).
  3. Make sure the class is public, has a public no-arg constructor, and is on the classpath (otherwise error 345 follows).
  4. If using Spring, prefer InitializingBean/Autowired approach or use DefaultKafkaProducerFactory which accepts the serializer instance directly rather than going through the class name property.

Example fix

// before
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
         new StringSerializer()); // instance -> ConfigException

// after
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
         StringSerializer.class.getName()); // FQCN
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
         StringSerializer.class); // Class object
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = rawValue;
if (!(v instanceof Class) && !(v instanceof String)) {
    throw new IllegalArgumentException("config '" + key + "' must be a Class instance or fully-qualified class name");
}

Type guard

public static boolean isClassValue(Object v) {
    return v instanceof Class || v instanceof String;
}

Try / catch

try {
    configDef.parse(configs);
} catch (ConfigException e) {
    if (e.getMessage().contains("Expected a Class instance or class name")) {
        // replace the value with a class name string and retry
    } else throw e;
}

Prevention

When it happens

Trigger: Constructing a producer/consumer/admin with a CLASS-typed config key set to an instance rather than the Class or class name — e.g. props.put("key.serializer", new MySerializer()) instead of props.put("key.serializer", MySerializer.class.getName()).

Common situations: New users confusing the serializer/deserializer instance with its class; DI frameworks that auto-wire an instance where the property expects the Class name; copy-pasting a bean reference instead of the FQCN; Spring Boot @Bean returning an instance injected into a Kafka property that wants a class name string.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/9d3178cdd580b7fa.json. Report an issue: GitHub.