elastic/elasticsearch · error · IllegalArgumentException

Unrecognized compile-time parameter(s): {}

Error message

Unrecognized compile-time parameter(s): {}

What it means

PainlessScriptEngine.buildCompilerSettings throws this IllegalArgumentException when, after stripping all recognized compile-time parameters from the params map, entries remain. Recognized keys are: max_loop_counter, painless.picky, painless.initial_call_site_depth (and the explicitly-rejected regex keys). Any other key is unknown to Painless and indicates a typo, a deprecated parameter, or a parameter belonging to a different scripting language.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java:453

            }

            value = copy.remove(CompilerSettings.INITIAL_CALL_SITE_DEPTH);
            if (value != null) {
                compilerSettings.setInitialCallSiteDepth(Integer.parseInt(value));
            }

            value = copy.remove(CompilerSettings.REGEX_ENABLED.getKey());
            if (value != null) {
                throw new IllegalArgumentException("[painless.regex.enabled] can only be set on node startup.");
            }

            value = copy.remove(CompilerSettings.REGEX_LIMIT_FACTOR.getKey());
            if (value != null) {
                throw new IllegalArgumentException("[painless.regex.limit-factor] can only be set on node startup.");
            }

            if (copy.isEmpty() == false) {
                throw new IllegalArgumentException("Unrecognized compile-time parameter(s): " + copy);
            }
        }
        return compilerSettings;
    }

    private static ScriptException convertToScriptException(String scriptSource, Throwable t) {
        // create a script stack: this is just the script portion
        List<String> scriptStack = new ArrayList<>();
        ScriptException.Position pos = null;
        for (StackTraceElement element : t.getStackTrace()) {
            if (WriterConstants.CLASS_NAME.equals(element.getClassName())) {
                // found the script portion
                int originalOffset = element.getLineNumber();
                if (originalOffset == -1) {
                    scriptStack.add("<<< unknown portion of script >>>");
                } else {
                    int offset = --originalOffset; // offset is 1 based, line numbers must be!
                    int startOffset = getPreviousStatement(offset);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Check the remaining keys in the error message (the 'copy' map is printed) and remove or correct each one.
  2. Ensure only these compile-time keys are used: painless.picky, painless.max_loop_counter, painless.initial_call_site_depth (regex keys are node-only).
  3. Move runtime variables into the script's runtime params (the separate params object), not the compile-time settings map.

Example fix

// before
{"source": "...", "params": {"painless.pick": true}}
// after
{"source": "...", "params": {"painless.picky": true}}
Defensive patterns

Strategy: validation

Validate before calling

// Only pass recognized compile-time keys in script params:
// // Valid: painless.picky, painless.max_loop_counter, painless.initial_call_site_depth
// // Validate before submitting: ensure no unknown keys remain

Prevention

When it happens

Trigger: Passing script params like {'painless.max_compilations_rate': ...}, {'lang': 'painless'}, or any key not in the recognized set. Mixing Painless params with params meant for mustache or expressions. Typos such as 'painless.pick' instead of 'painless.picky'.

Common situations: Copy-pasting settings from docs for a different ES version where parameter names changed. Confusing the script 'params' (runtime variables accessible in the script) with compile-time settings. Using deprecated parameter names after an upgrade.

Related errors


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