Type to search.

Debug array manipulation errors 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.

An array index_out_of_bounds_exception error occurs when a script tries to access an element at a position that does not exist in the array. For example, if an array has two elements, trying to access a third element triggers this exception.

Follow these guidelines to avoid array (list) access errors in your Painless scripts:

  • Array bounds: Always check the size of an array before accessing specific indices.
  • Zero-indexed: Remember that arrays start at index 0, so size() - 1 is the last valid index.
  • Empty arrays: Handle cases where arrays might be completely empty (size() == 0).

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

JSON
{
  "error": {
    "root_cause": [
      {
        "type": "index_out_of_bounds_exception",
        "reason": "index_out_of_bounds_exception: Index 2 out of bounds for length 2"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "blog_posts",
        "node": "hupWdkj_RtmThGjNUiIt_w",
        "reason": {
          "type": "script_exception",
          "reason": "runtime error",
          "script_stack": [
            "java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)",
            "java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)",
            "java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)",
            "java.base/java.util.Objects.checkIndex(Objects.java:365)",
            "java.base/java.util.ArrayList.get(ArrayList.java:428)",
            """return keywords[2].toUpperCase();
          """,
            "               ^---- HERE"
          ],
          "script": " ...",
          "lang": "painless",
          "position": {
            "offset": 76,
            "start": 61,
            "end": 105
          },
          "caused_by": {
            "type": "index_out_of_bounds_exception",
            "reason": "index_out_of_bounds_exception: Index 2 out of bounds for length 2"
          }
        }
      }
    ],
    "caused_by": {
      "type": "index_out_of_bounds_exception",
      "reason": "index_out_of_bounds_exception: Index 2 out of bounds for length 2"
    }
  },
  "status": 400
}
JSON
{
  "aggs": {
    "third_tag_stats": {
      "terms": {
        "script": {
          "source": """
            def keywords = params._source.tags;

            return keywords[2].toUpperCase();
          """,
          "lang": "painless"
        }
      }
    }
  }
}

The error occurs because the script tries to access index 2 (the third element) in an array that only has two elements (indices 0, 1). Arrays in Painless are zero-indexed, so accessing an index greater than or equal to the array size causes an exception.

Always verify the size of an array before accessing specific indices:

JSON
GET blog_posts/_search
{
  "size": 0,
  "aggs": {
    "third_tag_stats": {
      "terms": {
        "script": {
          "source": """
            def keywords = params._source.tags;

            if (keywords.size() > 2) {
              return keywords[2].toUpperCase();
            } else {
              return "NO_THIRD_TAG";
            }
          """,
          "lang": "painless"
        }
      }
    }
  }
}
JSON
POST blog_posts/_doc
{
  "title": "Getting Started with Elasticsearch",
  "content": "Learn the basics...",
  "tags": ["elasticsearch", "tutorial"]
}
JSON
{
  ...,
  "hits": {
    ...
  },
  "aggregations": {
    "third_tag_stats": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "NO_THIRD_TAG",
          "doc_count": 1
        }
      ]
    }
  }
}