provectus/kafka-ui · error · ValidationException

Dynamic config change is not allowed. Set…

Error message

Dynamic config change is not allowed. Set dynamic.config.enabled property to 'true' to enabled it.

What it means

checkIfDynamicConfigEnabled() gates the entire dynamic-config feature (viewing and persisting runtime properties). The feature is opt-in via `dynamic.config.enabled=true`; when it is off, any dynamic config read/write call throws this ValidationException before doing any work.

Solutions

  1. Set `dynamic.config.enabled: true` in application.yml (or DYNAMIC_CONFIG_ENABLED=true env var) and restart kafka-ui
  2. If runtime config changes are intentionally disabled, make the change in the application config file and restart instead
  3. Verify the property is under the top-level kafka-ui config, not nested incorrectly

Example fix

// before
# dynamic config not mentioned
// after
dynamic:
  config:
    enabled: true
Defensive patterns

Strategy: validation

Validate before calling

if (!dynamicConfigEnabled) {
  throw new IllegalStateException("Set dynamic.config.enabled=true to use dynamic config endpoints");
}

Try / catch

try {
  dynamicConfigOperations.persist(props);
} catch (ValidationException e) {
  if (e.getMessage().contains("Dynamic config")) {
    // guide user to enable the flag or apply config via file + restart
  }
}

Prevention

When it happens

Trigger: Calling dynamic config endpoints (getCurrentProperties, persist, uploadConfigRelatedFile) when the application was started without `dynamic.config.enabled: true` / env var DYNAMIC_CONFIG_ENABLED=true.

Common situations: Default deployment without the flag, then an admin tries to change config from the UI; container image where the env var was dropped during a config refactor.

Related errors


AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08). Data as JSON: /api/errors/4deeb55c27c69d6e. Report an issue: GitHub.

Appendix: source

Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/DynamicConfigOperations.java:165

    }

    return file.transferTo(targetFilePath)
        .thenReturn(targetFilePath)
        .doOnError(th -> log.error("Error uploading file {}", targetFilePath, th))
        .onErrorMap(th -> new FileUploadException(targetFilePath, th));
  }

  public void checkIfFilteringGroovyEnabled() {
    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(

View on GitHub (pinned to 83b5a60cc0)