Type to search.

Debug regex pattern matching failures in Painless

Serverless

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Serverless interfaces and procedures might differ from classic Elastic Stack deployments.

Stack

The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments.

This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.

Regex operations in Painless can fail for several reasons: the regex feature is deactivated, there is incorrect matcher usage, or there are malformed regex patterns. This can occur when standard Java regex behavior is thought to apply directly to Painless.

Follow these guidelines to avoid regex operation errors in your Painless scripts:

  • Call find() first: Always use matcher.find() before accessing groups.
  • Enable regex: Set script.painless.regex.enabled=true in the elasticsearch.yml settings 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.

For details, refer to the following sample error, solution, and the result when the solution is applied.

JSON
{
  "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
}
JSON
{
  "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:

JSON
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";
    """
  }
}
JSON
{
  "result": "SHIP-EX EXPRESS DELIVERY"
}