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.

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.

Appendix: 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)