{"record":{"id":"b8cd5e0198d0e3b7","repo":"elastic/elasticsearch","slug":"painless-regex-limit-factor-can-only-be-set-on-n","errorCode":null,"errorMessage":"[painless.regex.limit-factor] can only be set on node startup.","messagePattern":"\\[painless\\.regex\\.limit-factor\\] can only be set on node startup\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java","lineNumber":449,"sourceCode":"\n            value = copy.remove(CompilerSettings.PICKY);\n            if (value != null) {\n                compilerSettings.setPicky(Booleans.parseBoolean(value));\n            }\n\n            value = copy.remove(CompilerSettings.INITIAL_CALL_SITE_DEPTH);\n            if (value != null) {\n                compilerSettings.setInitialCallSiteDepth(Integer.parseInt(value));\n            }\n\n            value = copy.remove(CompilerSettings.REGEX_ENABLED.getKey());\n            if (value != null) {\n                throw new IllegalArgumentException(\"[painless.regex.enabled] can only be set on node startup.\");\n            }\n\n            value = copy.remove(CompilerSettings.REGEX_LIMIT_FACTOR.getKey());\n            if (value != null) {\n                throw new IllegalArgumentException(\"[painless.regex.limit-factor] can only be set on node startup.\");\n            }\n\n            if (copy.isEmpty() == false) {\n                throw new IllegalArgumentException(\"Unrecognized compile-time parameter(s): \" + copy);\n            }\n        }\n        return compilerSettings;\n    }\n\n    private static ScriptException convertToScriptException(String scriptSource, Throwable t) {\n        // create a script stack: this is just the script portion\n        List<String> scriptStack = new ArrayList<>();\n        ScriptException.Position pos = null;\n        for (StackTraceElement element : t.getStackTrace()) {\n            if (WriterConstants.CLASS_NAME.equals(element.getClassName())) {\n                // found the script portion\n                int originalOffset = element.getLineNumber();\n                if (originalOffset == -1) {","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java#L431-L467","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (script params)\n{\"source\": \"...\", \"params\": {\"painless.regex.limit-factor\": 50}}\n// after (elasticsearch.yml)\nscript.painless.regex.limit-factor: 50","handlingStrategy":"validation","validationCode":"// Do not include painless.regex.limit-factor in script params. Set it at node level:\n// // elasticsearch.yml: script.painless.regex.limit-factor: 50","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["painless","elasticsearch","configuration","regex","settings","compile-time"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}