provectus/kafka-ui · error · ValidationException
'filePath' property not set for custom serde
Error message
'filePath' property not set for custom serde ${serdeConfig.getName()} What it means
Kafka UI's SerdesInitializer validates every custom serde config before loading it. A custom serde must specify both the fully-qualified 'className' of the Serde implementation and the 'filePath' of the JAR containing it; when filePath is null or empty the initializer refuses to proceed because the class cannot be located without its archive. It throws a ValidationException naming the offending serde.
Solutions
- Add the 'filePath' property pointing to the custom serde JAR to the serde config
- Verify the property name spelling (filePath) and that the value is non-empty in application.yaml or the API request payload
- If the JAR is bundled, set filePath to its classpath-relative or absolute path accessible to the kafka-ui process
Example fix
// before
serde:
- name: my-serde
className: com.example.MySerde
// after
serde:
- name: my-serde
className: com.example.MySerde
filePath: /etc/kafka-ui/serde/my-serde.jar Defensive patterns
Strategy: validation
Validate before calling
if (cfg == null || cfg.getClassName() == null || cfg.getClassName().isBlank() || cfg.getFilePath() == null || cfg.getFilePath().isBlank()) { throw new IllegalArgumentException("custom serde needs both className and filePath"); } Type guard
boolean isValidCustomSerde(c) { return c != null && !isNullOrEmpty(c.getClassName()) && !isNullOrEmpty(c.getFilePath()); } Try / catch
try { serde = initCustomSerde(cfg); } catch (ValidationException e) { log.error("bad serde config: {}", e.getMessage()); } Prevention
- Always set filePath (JAR location) whenever className is set for a custom serde
- Validate serde config keys against a schema at startup
- Keep serde JAR paths in one well-documented config section
When it happens
Trigger: Calling createSerdeFromConfig / loadAndInitCustomSerde with a CustomSerde config whose filePath property is missing, empty, or set to null (e.g. only className was specified in serdeConfig).
Common situations: Hand-writing serde config in application.yaml/properties and forgetting the filePath key; copying a serde config snippet that only sets className; programmatically building a CustomSerde and leaving filePath unset.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Invalid format for webclient.maxInMemoryBufferSize
- 'name' property not set for serde
- Multiple serdes with same name
- className can't be set for built-in serde
- filePath can't be set for built-in serde types
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/bb618b61ea67125f.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/serdes/SerdesInitializer.java:263
null
);
}
@SneakyThrows
private <T extends Serde> T createSerdeInstance(Class<T> clazz) {
return clazz.getDeclaredConstructor().newInstance();
}
private SerdeInstance loadAndInitCustomSerde(SerdeConfig serdeConfig,
PropertyResolver serdeProps,
PropertyResolver clusterProps,
PropertyResolver globalProps) {
if (Strings.isNullOrEmpty(serdeConfig.getClassName())) {
throw new ValidationException(
"'className' property not set for custom serde " + serdeConfig.getName());
}
if (Strings.isNullOrEmpty(serdeConfig.getFilePath())) {
throw new ValidationException(
"'filePath' property not set for custom serde " + serdeConfig.getName());
}
var loaded = customSerdeLoader.loadAndConfigure(
serdeConfig.getClassName(), serdeConfig.getFilePath(), serdeProps, clusterProps, globalProps);
return new SerdeInstance(
serdeConfig.getName(),
loaded.getSerde(),
nullablePattern(serdeConfig.getTopicKeysPattern()),
nullablePattern(serdeConfig.getTopicValuesPattern()),
loaded.getClassLoader()
);
}
@Nullable
private Pattern nullablePattern(@Nullable String pattern) {
return pattern == null ? null : Pattern.compile(pattern);
}
}View on GitHub (pinned to 83b5a60cc0)