elastic/elasticsearch · error · IllegalArgumentException

Testclusters does not allow the following settings to be cha

Error message

Testclusters does not allow the following settings to be changed:{} for {}

What it means

Thrown in createConfiguration() when the set of config keys the caller supplied via node.setting(...) overlaps baseConfig keys that are NOT in OVERRIDABLE_SETTINGS. The plugin protects a fixed set of internal config keys (path.data, path.logs, node.name, node.processors, action.destructive_requires_name, etc.) because they are managed by the harness itself.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:1453

            baseConfig.put("cluster.service.slow_master_task_logging_threshold", "5s");
        }

        // Limit the number of allocated processors for all nodes in the cluster by default.
        // This is to ensure that the tests run consistently across different environments.
        String processorCount = shouldConfigureTestClustersWithOneProcessor() ? "1" : "2";
        if (getVersion().onOrAfter("7.4.0")) {
            baseConfig.put("node.processors", processorCount);
        } else {
            baseConfig.put("processors", processorCount);
        }

        baseConfig.put("action.destructive_requires_name", "false");

        HashSet<String> overriden = new HashSet<>(baseConfig.keySet());
        overriden.retainAll(settings.keySet());
        overriden.removeAll(OVERRIDABLE_SETTINGS);
        if (overriden.isEmpty() == false) {
            throw new IllegalArgumentException(
                "Testclusters does not allow the following settings to be changed:" + overriden + " for " + this
            );
        }
        // Make sure no duplicate config keys
        settings.keySet().stream().filter(OVERRIDABLE_SETTINGS::contains).forEach(baseConfig::remove);

        final Path configFileRoot = configFile.getParent();
        try {
            Files.writeString(
                configFile,
                Stream.concat(settings.entrySet().stream(), baseConfig.entrySet().stream())
                    .map(entry -> entry.getKey() + ": " + entry.getValue())
                    .collect(Collectors.joining("\n")),
                StandardOpenOption.TRUNCATE_EXISTING,
                StandardOpenOption.CREATE
            );

            final List<Path> configFiles;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove the offending key from your node.setting(...) call — the message names the exact set in 'overriden'.
  2. If you genuinely need to change one of these, check OVERRIDABLE_SETTINGS for the key; if it is listed there it is allowed, otherwise the harness owns it.
  3. For path.data/path.logs, use node.setDataPath(Path) or the dataDir mechanism on RunTask instead of the raw setting.
  4. For cluster name, use the cluster's naming API rather than 'cluster.name' via setting().

Example fix

// before:
node.setting("node.processors", 2);  // protected, throws
// after:
node.setProcessors(2);  // or omit — let the harness compute it
Defensive patterns

Strategy: validation

Validate before calling

Set<String> conflict = new HashSet<>(yourSettings.keySet());
conflict.retainAll(BASE_CONFIG_KEYS);  // path.data, node.name, node.processors, ...
conflict.removeAll(OVERRIDABLE_SETTINGS);
if (!conflict.isEmpty()) {
    throw new IllegalArgumentException("Refusing protected settings: " + conflict);
}

Prevention

When it happens

Trigger: A test or plugin calls node.setting("path.data", ...) (or any protected key) with a value that conflicts with what the plugin already set in baseConfig. The intersection of the user's settings and baseConfig, minus OVERRIDABLE_SETTINGS, is non-empty.

Common situations: A build.gradle adds a setting like 'node.name', 'path.repo', 'processors', 'node.processors', or 'action.destructive_requires_name' via setting(...) — these are all plugin-managed. Usually a copy-paste from an older distributions-test that allowed them.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/32fd929ffc6b97b6. Report an issue: GitHub.