---
type: api
title: Explain the shard allocations
description: **All methods and paths for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4493/api/doc/elasticsearch/v8/operation/operation-cluster-allocation-explain
resource: https://www.elastic.co/elastic/docs-builder/docs/4493/api/doc/elasticsearch/v8/operation/operation-cluster-allocation-explain
products:
  - Elasticsearch
---

# Explain the shard allocations


Availability: Generally available since 5.0

## Paths

- `POST` (also `GET`) `/_cluster/allocation/explain`

## Description

Get explanations for shard allocations in the cluster.
For unassigned shards, it provides an explanation for why the shard is unassigned.
For assigned shards, it provides an explanation for why the shard is remaining on its current node and has not moved or rebalanced to another node.
This API can be very useful when attempting to diagnose why a shard is unassigned or why a shard continues to remain on its current node when you might expect otherwise.

## Authentication

- Api key: `Authorization: <value>`
  Elasticsearch APIs support key-based authentication.
  You must create an API key and use the encoded value in the request header.
  For example:
  
  
  ```
  curl -X GET "${ES_URL}/_cat/indices?v=true" \
    -H "Authorization: ApiKey ${API_KEY}"
  ```
  
  To get API keys, use the `/_security/api_key` APIs.
- Basic: `Authorization: Basic <credentials>`
- Bearer: `Authorization: Bearer <token>`
  Elasticsearch APIs support the use of bearer tokens in the `Authorization` HTTP header to authenticate with the API.
  For examples, refer to [Token-based authentication services](https://www.elastic.co/guide/en/elasticsearch/reference/current/token-authentication-services.html)

## Query string parameters

- `include_disk_info` (boolean · default: false) — optional
  If true, returns information about disk usage and shard sizes.
- `include_yes_decisions` (boolean · default: false) — optional
  If true, returns YES decisions in explanation.
- `master_timeout` (string · default: 30s) — optional
  Period to wait for a connection to the master node.

## Request body

`application/json`

- `current_node` (string) — optional
  Specifies the node ID or the name of the node to only explain a shard that is currently located on the specified node.
- `index` (string) — optional
  Specifies the name of the index that you would like an explanation for.
- `primary` (boolean) — optional
  If true, returns explanation for the primary shard for the given shard ID.
- `shard` (number) — optional
  Specifies the ID of the shard that you would like an explanation for.

## Response

`application/json`

- `allocate_explanation` (string)
- `allocation_delay` (string)
- `allocation_delay_in_millis` (number)
- `can_allocate` (enum)
  Values: `yes`, `no`, `worse_balance`, `throttled`, `awaiting_info`, `allocation_delayed`, `no_valid_shard_copy`, `no_attempt`
- `can_move_to_other_node` (enum)
  Values: `yes`, `no`, `worse_balance`, `throttled`, `awaiting_info`, `allocation_delayed`, `no_valid_shard_copy`, `no_attempt`
- `can_rebalance_cluster` (enum)
  Values: `yes`, `no`, `worse_balance`, `throttled`, `awaiting_info`, `allocation_delayed`, `no_valid_shard_copy`, `no_attempt`
- `can_rebalance_cluster_decisions` (object[])
  - `decider` (string)
  - `decision` (enum)
    Values: `NO`, `YES`, `THROTTLE`, `ALWAYS`
  - `explanation` (string)
- `can_rebalance_to_other_node` (enum)
  Values: `yes`, `no`, `worse_balance`, `throttled`, `awaiting_info`, `allocation_delayed`, `no_valid_shard_copy`, `no_attempt`
- `can_remain_decisions` (object[])
  - `decider` (string)
  - `decision` (enum)
    Values: `NO`, `YES`, `THROTTLE`, `ALWAYS`
  - `explanation` (string)
- `can_remain_on_current_node` (enum)
  Values: `yes`, `no`, `worse_balance`, `throttled`, `awaiting_info`, `allocation_delayed`, `no_valid_shard_copy`, `no_attempt`
- `cluster_info` (object)
  - `nodes` (map string to object)
    Map values (object)
    - `node_name` (string)
    - `least_available` (object)
      - `path` (string)
      - `total_bytes` (number)
      - `used_bytes` (number)
      - `free_bytes` (number)
      - `free_disk_percent` (number)
      - `used_disk_percent` (number)
    - `most_available` (object)
      - `path` (string)
      - `total_bytes` (number)
      - `used_bytes` (number)
      - `free_bytes` (number)
      - `free_disk_percent` (number)
      - `used_disk_percent` (number)
  - `shard_sizes` (map string to number)
  - `shard_data_set_sizes` (map string to string)
  - `shard_paths` (map string to string)
  - `reserved_sizes` (object[])
    - `node_id` (string)
    - `path` (string)
    - `total` (number)
    - `shards` (string[])
- `configured_delay` (string)
- `configured_delay_in_millis` (number)
- `current_node` (object)
  - `id` (string)
  - `name` (string)
  - `roles` (enum[])
    Values: `master`, `data`, `data_cold`, `data_content`, `data_frozen`, `data_hot`, `data_warm`, `client`, `ingest`, `ml`, `voting_only`, `transform`, `remote_cluster_client`, `coordinating_only`
  - `attributes` (map string to string)
  - `transport_address` (string)
  - `weight_ranking` (number)
- `current_state` (string)
- `index` (string)
- `move_explanation` (string)
- `node_allocation_decisions` (object[])
  - `deciders` (object[])
    - `decider` (string)
    - `decision` (enum)
      Values: `NO`, `YES`, `THROTTLE`, `ALWAYS`
    - `explanation` (string)
  - `node_attributes` (map string to string)
  - `node_decision` (enum)
    Values: `yes`, `no`, `worse_balance`, `throttled`, `awaiting_info`, `allocation_delayed`, `no_valid_shard_copy`, `no_attempt`
  - `node_id` (string)
  - `node_name` (string)
  - `roles` (enum[])
    Values: `master`, `data`, `data_cold`, `data_content`, `data_frozen`, `data_hot`, `data_warm`, `client`, `ingest`, `ml`, `voting_only`, `transform`, `remote_cluster_client`, `coordinating_only`
  - `store` (object)
    - `allocation_id` (string)
    - `found` (boolean)
    - `in_sync` (boolean)
    - `matching_size_in_bytes` (number)
    - `matching_sync_id` (boolean)
    - `store_exception` (string)
  - `transport_address` (string)
  - `weight_ranking` (number)
- `primary` (boolean)
- `rebalance_explanation` (string)
- `remaining_delay` (string)
- `remaining_delay_in_millis` (number)
- `shard` (number)
- `unassigned_info` (object)
  - `at` (union)
  - `last_allocation_status` (string)
  - `reason` (enum)
    Values: `INDEX_CREATED`, `CLUSTER_RECOVERED`, `INDEX_REOPENED`, `DANGLING_INDEX_IMPORTED`, `NEW_INDEX_RESTORED`, `EXISTING_INDEX_RESTORED`, `REPLICA_ADDED`, `ALLOCATION_FAILED`, `NODE_LEFT`, `REROUTE_CANCELLED`, `REINITIALIZED`, `REALLOCATED_REPLICA`, `PRIMARY_FAILED`, `FORCED_EMPTY_PRIMARY`, `MANUAL_ALLOCATION`
  - `details` (string)
  - `failed_allocation_attempts` (number)
  - `delayed` (boolean)
  - `allocation_status` (string)
- `note` (string)
## Code examples

#### Console

```console
POST _cluster/allocation/explain
{
  "index": "my-index-000001",
  "shard": 0,
  "primary": false,
  "current_node": "my-node"
}
```

#### JavaScript

```javascript
const response = await client.cluster.allocationExplain({
  index: "my-index-000001",
  shard: 0,
  primary: false,
  current_node: "my-node",
});
```

#### Python

```python
resp = client.cluster.allocation_explain(
    index="my-index-000001",
    shard=0,
    primary=False,
    current_node="my-node",
)
```

#### curl

```curl
curl -X POST "$ELASTICSEARCH_URL/_cluster/allocation/explain" \
  -H "Authorization: ApiKey $ELASTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "index": "my-index-000001",
    "shard": 0,
    "primary": false,
    "current_node": "my-node"
  }'
```

#### Java

```java
client.cluster().allocationExplain(a -> a
    .currentNode("my-node")
    .index("my-index-000001")
    .primary(false)
    .shard(0)
);
```

#### C#

```c#
var response = await client.Cluster
    .AllocationExplainAsync(d1 => d1
        .CurrentNode("my-node")
        .Index("my-index-000001")
        .Primary(false)
        .Shard(0)
    );
```

#### PHP

```php
$resp = $client->cluster()->allocationExplain([
    "body" => [
        "index" => "my-index-000001",
        "shard" => 0,
        "primary" => false,
        "current_node" => "my-node",
    ],
]);
```

#### Ruby

```ruby
response = client.cluster.allocation_explain(
  body: {
    "index": "my-index-000001",
    "shard": 0,
    "primary": false,
    "current_node": "my-node"
  }
)
```

## Response examples

#### Conflicting settings

An example of an allocation explanation for an unassigned primary shard. In this example, a newly created index has an index setting that requires that it only be allocated to a node named `nonexistent_node`, which does not exist, so the index is unable to allocate.

```json
{
  "index" : "my-index-000001",
  "shard" : 0,
  "primary" : true,
  "current_state" : "unassigned",
  "unassigned_info" : {
    "reason" : "INDEX_CREATED",
    "at" : "2017-01-04T18:08:16.600Z",
    "last_allocation_status" : "no"
  },
  "can_allocate" : "no",
  "allocate_explanation" : "Elasticsearch isn't allowed to allocate this shard to any of the nodes in the cluster. Choose a node to which you expect this shard to be allocated, find this node in the node-by-node explanation, and address the reasons which prevent Elasticsearch from allocating this shard there.",
  "node_allocation_decisions" : [
    {
      "node_id" : "8qt2rY-pT6KNZB3-hGfLnw",
      "node_name" : "node-0",
      "transport_address" : "127.0.0.1:9401",
      "roles" : ["data", "data_cold", "data_content", "data_frozen", "data_hot", "data_warm", "ingest", "master", "ml", "remote_cluster_client", "transform"],
      "node_attributes" : {},
      "node_decision" : "no",
      "weight_ranking" : 1,
      "deciders" : [
        {
          "decider" : "filter",
          "decision" : "NO",
          "explanation" : "node does not match index setting [index.routing.allocation.include] filters [_name:\"nonexistent_node\"]"
        }
      ]
    }
  ]
}
```

#### Maximum retries

An example of an allocation explanation for an unassigned primary shard that has reached the maximum number of allocation retry attempts. After the maximum number of retries is reached, Elasticsearch stops attempting to allocate the shard in order to prevent infinite retries which may impact cluster performance.

```json
{
  "index" : "my-index-000001",
  "shard" : 0,
  "primary" : true,
  "current_state" : "unassigned",
  "unassigned_info" : {
    "at" : "2017-01-04T18:03:28.464Z",
    "failed shard on node [mEKjwwzLT1yJVb8UxT6anw]: failed recovery, failure RecoveryFailedException",
    "reason": "ALLOCATION_FAILED",
    "failed_allocation_attempts": 5,
    "last_allocation_status": "no",
  },
  "can_allocate": "no",
  "allocate_explanation": "cannot allocate because allocation is not permitted to any of the nodes",
  "node_allocation_decisions" : [
    {
      "node_id" : "3sULLVJrRneSg0EfBB-2Ew",
      "node_name" : "node_t0",
      "transport_address" : "127.0.0.1:9400",
      "roles" : ["data_content", "data_hot"],
      "node_decision" : "no",
      "store" : {
        "matching_size" : "4.2kb",
        "matching_size_in_bytes" : 4325
      },
      "deciders" : [
        {
          "decider": "max_retry",
          "decision" : "NO",
          "explanation": "shard has exceeded the maximum number of retries [5] on failed allocation attempts - manually call [POST /_cluster/reroute?retry_failed] to retry, [unassigned_info[[reason=ALLOCATION_FAILED], at[2024-07-30T21:04:12.166Z], failed_attempts[5], failed_nodes[[mEKjwwzLT1yJVb8UxT6anw]], delayed=false, details[failed shard on node [mEKjwwzLT1yJVb8UxT6anw]: failed recovery, failure RecoveryFailedException], allocation_status[deciders_no]]]"
        }
      ]
    }
  ]
}
```

