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

  1. Change dynamic.config.path to a full file path inside an existing directory (e.g. /etc/kafka-ui/application-config.yml)
  2. Restart kafka-ui with the corrected value
  3. 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

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


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)