elastic/elasticsearch · error · IllegalArgumentException
[painless.regex.limit-factor] can only be set on node startu
Error message
[painless.regex.limit-factor] can only be set on node startup.
What it means
PainlessScriptEngine.buildCompilerSettings throws this IllegalArgumentException when a per-script compile parameter includes 'painless.regex.limit-factor'. This setting caps regex complexity (the automaton state expansion factor) and is a node-level security control; it cannot be tuned per request. Like regex.enabled, it is only read from the node's context defaults at startup.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java:449
value = copy.remove(CompilerSettings.PICKY);
if (value != null) {
compilerSettings.setPicky(Booleans.parseBoolean(value));
}
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) {View on GitHub (pinned to db6a809a66)
Solutions
- Set script.painless.regex.limit-factor in elasticsearch.yml or via the cluster settings API, then restart/reload.
- Remove the key from the script's params map.
- If regexes are hitting the limit, simplify the regex pattern rather than tuning the limit per-script.
Example fix
// before (script params)
{"source": "...", "params": {"painless.regex.limit-factor": 50}}
// after (elasticsearch.yml)
script.painless.regex.limit-factor: 50 Defensive patterns
Strategy: validation
Validate before calling
// Do not include painless.regex.limit-factor in script params. Set it at node level: // // elasticsearch.yml: script.painless.regex.limit-factor: 50
Prevention
- Set painless.regex.limit-factor at the node level only.
- Simplify regex patterns instead of tuning the limit per query.
- Keep node-level and per-script settings separate in configuration management.
When it happens
Trigger: Submitting a script with params containing {'painless.regex.limit-factor': '100'} in any compilation context (ingest, search, runtime fields). The buildCompilerSettings method detects the key in the params copy and rejects it.
Common situations: Attempting to raise or lower the regex complexity limit per-query to work around a regex timeout. Confusing node settings with script params. Porting configuration between environments.
Related errors
- [painless.regex.enabled] can only be set on node startup.
- Unrecognized compile-time parameter(s): {}
- invalid value [{}] must be one of [true,false,limited]
- failed to parse value [{}] for setting [{}], must be [-1b] (
- Cannot apply operator [{}] to type [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b8cd5e0198d0e3b7.
Report an issue: GitHub.