Troubleshoot regex pattern matching failures in Painless
Serverless Stack
Follow these guidelines to avoid regex operation errors in your Painless scripts.
Regex operations in Painless can fail for several reasons: the regex feature is disabled, there is incorrect matcher usage, or there are malformed regex patterns. This may occur when standard Java regex behavior is thought to apply directly to Painless.
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"java.base/java.util.regex.Matcher.checkMatch(Matcher.java:1850)",
"java.base/java.util.regex.Matcher.group(Matcher.java:685)",
"""return /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog).group(0);
""",
" ^---- HERE"
],
"script": " ...",
"lang": "painless",
"position": {
"offset": 176,
"start": 126,
"end": 191
}
}
],
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"java.base/java.util.regex.Matcher.checkMatch(Matcher.java:1850)",
"java.base/java.util.regex.Matcher.group(Matcher.java:685)",
"""return /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog).group(0);
""",
" ^---- HERE"
],
"script": " ...",
"lang": "painless",
"position": {
"offset": 176,
"start": 126,
"end": 191
},
"caused_by": {
"type": "illegal_state_exception",
"reason": "No match found"
}
},
"status": 400
}
{
"script": {
"lang": "painless",
"source": """
String orderLog = "Order processing initiated\\nSHIPPER: SHIP-EX EXPRESS DELIVERY\\nTracking number generated";
return /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog).group(0);
"""
}
}
The error occurs because the group() method is called on a Matcher before calling find(). You must explicitly search for matches before accessing groups. This is a common mistake when developers expect the matcher to automatically find matches.
Always call find() before using group() methods:
POST _scripts/painless/_execute
{
"script": {
"lang": "painless",
"source": """
String orderLog = "Order processing initiated\\nSHIPPER: SHIP-EX EXPRESS DELIVERY\\nTracking number generated";
Matcher m = /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog);
boolean found = m.find();
return found ? m.group(0).trim() : "No match";
"""
}
}
{
"result": "SHIP-EX EXPRESS DELIVERY"
}
- Call find() first: Always use
matcher.find()before accessing groups. - Enable regex: Set
script.painless.regex.enabled=truein theelasticsearch.ymlsettings file if regex is disabled. - Group numbering: Use
group(0)for the entire match,group(1)for first capture group, and so on. - Performance impact: Regex operations can be expensive, especially with complex patterns.