provectus/kafka-ui · error · ValidationException
className can't be set for built-in serde
Error message
className can't be set for built-in serde
What it means
Serde names that match built-in serde types (e.g. protobuf, avro-schema-registry) are instantiated from internal classes; supplying a className would conflict with the built-in class resolution, so createSerdeWithBuiltInSerdeName throws ValidationException.
Solutions
- Remove the className field from the entry using the built-in serde name
- Or rename the serde to a non-built-in name if you actually want a custom class
Example fix
// before
serde:
- name: protobuf
className: com.provectus.kafka.ui.serdes.builtin.ProtobufSerde
// after
serde:
- name: protobuf Defensive patterns
Strategy: validation
Validate before calling
if (isBuiltInSerdeName(cfg.getName()) && cfg.getClassName() != null)
throw new IllegalArgumentException("className not allowed for built-in serde " + cfg.getName()); Try / catch
try {
serde = createSerdeFromConfig(cfg, ...);
} catch (ValidationException e) {
log.error("Bad serde config for {}: {}", cfg.getName(), e.getMessage());
throw e;
} Prevention
- Use the minimal config template for built-in serdes (name + optional properties)
- Only set className for genuinely custom serdes
- Document which names are reserved built-in serde names
When it happens
Trigger: Using a built-in serde name in config while also setting className on the same serde entry.
Common situations: User copies a custom-serde config template and edits only filePath, leaving className set while keeping a built-in name like 'protobuf'.
Related errors
- filePath can't be set for built-in serde types
- serde is not configured
- filePath can't be set for built-in serde type
- 'name' property not set for serde
- Multiple serdes with same name
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/86ebccfe89369796.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/serdes/SerdesInitializer.java:196
var builtInSerdeClass = builtInSerdeClasses.values().stream()
.filter(c -> c.getName().equals(serdeConfig.getClassName()))
.findAny();
// built-in serde type with custom name
if (builtInSerdeClass.isPresent()) {
return createSerdeWithBuiltInClass(builtInSerdeClass.get(), serdeConfig, serdeProps, clusterProps, globalProps);
}
}
log.info("Loading custom serde {}", serdeConfig.getName());
return loadAndInitCustomSerde(serdeConfig, serdeProps, clusterProps, globalProps);
}
private SerdeInstance createSerdeWithBuiltInSerdeName(SerdeConfig serdeConfig,
PropertyResolver serdeProps,
PropertyResolver clusterProps,
PropertyResolver globalProps) {
String name = serdeConfig.getName();
if (serdeConfig.getClassName() != null) {
throw new ValidationException("className can't be set for built-in serde");
}
if (serdeConfig.getFilePath() != null) {
throw new ValidationException("filePath can't be set for built-in serde types");
}
var clazz = builtInSerdeClasses.get(name);
BuiltInSerde serde = createSerdeInstance(clazz);
if (serdeConfig.getProperties() == null || serdeConfig.getProperties().isEmpty()) {
if (!autoConfigureSerde(serde, clusterProps, globalProps)) {
// no properties provided and serde does not support auto-configuration
throw new ValidationException(name + " serde is not configured");
}
} else {
// configuring serde with explicitly set properties
serde.configure(serdeProps, clusterProps, globalProps);
}
return new SerdeInstance(
name,
serde,View on GitHub (pinned to 83b5a60cc0)