provectus/kafka-ui · error · ValidationException
Dynamic file path is a directory, but should be a file path
Error message
Dynamic file path is a directory, but should be a file path
What it means
writeYamlToFile() persists the serialized dynamic config YAML to the path configured by `dynamic.config.path`. Before writing it checks Files.isDirectory(path); if the configured path points at an existing directory it throws this ValidationException, since a directory cannot be used as the config file.
Solutions
- Change dynamic.config.path to a full file path inside an existing directory (e.g. /etc/kafka-ui/application-config.yml)
- Restart kafka-ui with the corrected value
- If a directory was mounted for this purpose, keep the directory mount but point the property at a file name inside it
Example fix
// before
dynamic:
config:
path: /etc/kafka-ui/
// after
dynamic:
config:
path: /etc/kafka-ui/application-config.yml Defensive patterns
Strategy: validation
Validate before calling
Path p = Path.of(configPath);
if (Files.isDirectory(p)) {
throw new IllegalArgumentException("dynamic.config.path must be a file path, not a directory: " + configPath);
} Try / catch
try {
dynamicConfigOperations.persist(props);
} catch (ValidationException e) {
if (e.getMessage().startsWith("Dynamic file path")) {
// fix the configured path and retry
}
} Prevention
- Always set dynamic.config.path to a full filename, not a directory
- Validate the path in a startup/init container
- Use helm template checks to assert the value ends with .yml/.yaml
When it happens
Trigger: `dynamic.config.path` (or DYNAMIC_CONFIG_PATH env var) set to a directory such as `/etc/kafka-ui/` or `/tmp` instead of a full file path like `/etc/kafka-ui/application-config.yml`; persist() then calls writeYamlToFile and fails.
Common situations: Mounting a volume directory and pointing the property at the mount root; dropping the filename when templating the value in Helm/Kubernetes manifests.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Dynamic config change is not allowed. Set…
- File already exists and is not writable
- Error writing to
- Application config isn't valid. Cluster names should be…
- Application config isn't valid. Two clusters can't have the…
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/9b9020c4d8d71512.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/DynamicConfigOperations.java:174
if (!filteringGroovyEnabled()) {
throw new ValidationException(
"Groovy filters is not allowed. "
+ "Set filtering.groovy.enabled property to 'true' to enabled it.");
}
}
private void checkIfDynamicConfigEnabled() {
if (!dynamicConfigEnabled()) {
throw new ValidationException(
"Dynamic config change is not allowed. "
+ "Set dynamic.config.enabled property to 'true' to enabled it.");
}
}
@SneakyThrows
private void writeYamlToFile(String yaml, Path path) {
if (Files.isDirectory(path)) {
throw new ValidationException("Dynamic file path is a directory, but should be a file path");
}
if (!Files.exists(path.getParent())) {
Files.createDirectories(path.getParent());
}
if (Files.exists(path) && !Files.isWritable(path)) {
throw new ValidationException("File already exists and is not writable");
}
try {
Files.writeString(
path,
yaml,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING // to override existing file
);
} catch (IOException e) {
throw new ValidationException("Error writing to " + path, e);
}View on GitHub (pinned to 83b5a60cc0)