How to restore Elasticsearch snapshots

Restoring an Elasticsearch snapshot recovers index or data stream contents from a repository after accidental deletion, corruption, or a failed migration. The restore API rebuilds the selected shards from the snapshot copy instead of relying on node-local data paths.

A restore request reads snapshot metadata from a registered snapshot repository, recreates the selected shards, and uses shard recovery to bring the restored primaries back online. The repository must already be available to the target cluster, and the snapshot, cluster, and restored index versions must be compatible. Use the same scheme, credentials, API key, and CA trust that other cluster API calls require.

A routine restore should target specific indices or data streams and keep include_global_state set to false so templates, ingest pipelines, persistent settings, and feature states are not rolled back unexpectedly. An existing open index with the same name blocks an in-place restore, while an existing closed index must have the same primary shard count as the snapshot. Elasticsearch opens restored indices automatically after recovery completes, and data stream restores need a matching data-stream-enabled index template on the target cluster.

Steps to restore Elasticsearch snapshots:

  1. List the snapshots in the repository before choosing a restore point.
    $ curl -sS --fail "http://localhost:9200/_cat/snapshots/local_fs?v"
    id                   repository  status start_epoch start_time end_epoch  end_time duration indices successful_shards failed_shards total_shards
    snapshot-restore-001 local_fs   SUCCESS 1781760465  05:27:45   1781760465 05:27:45       0s       1                 1             0            1

    CAT snapshot output is intended for operator checks in the terminal. Use the get snapshot API in the next step when the restore decision depends on the exact snapshot contents.

  2. Inspect the chosen snapshot to confirm the indices, data streams, and cluster-state scope.
    $ curl -sS --fail "http://localhost:9200/_snapshot/local_fs/snapshot-restore-001?pretty&filter_path=snapshots.snapshot,snapshots.indices,snapshots.data_streams,snapshots.include_global_state,snapshots.feature_states,snapshots.state"
    {
      "snapshots" : [
        {
          "snapshot" : "snapshot-restore-001",
          "indices" : [
            "logs-2026.04"
          ],
          "data_streams" : [ ],
          "include_global_state" : false,
          "state" : "SUCCESS",
          "feature_states" : [ ]
        }
      ]
    }

    The get snapshot API is the exact source of snapshot contents. If the expected index is missing here, it was not captured in that snapshot. When feature_states is non-empty, restoring system data requires the matching feature-state workflow.

  3. Check whether an index with the target name already exists.
    $ curl -sS -o /dev/null -w "%{http_code}\n" "http://localhost:9200/logs-2026.04"
    200

    A response of 200 indicates the index exists, while 404 indicates no index exists to close.

  4. Close the target index if it already exists.
    $ curl -sS --fail -X POST "http://localhost:9200/logs-2026.04/_close?pretty"
    {
      "acknowledged" : true,
      "shards_acknowledged" : true,
      "indices" : {
        "logs-2026.04" : {
          "closed" : true
        }
      }
    }

    Elasticsearch can restore over an existing index only when it is closed and has the same number of primary shards as the snapshot. If the current index must stay online, restore under a new name with rename_pattern and rename_replacement instead.

  5. Start the asynchronous restore request for the required indices.
    $ curl -sS --fail -H "Content-Type: application/json" -X POST "http://localhost:9200/_snapshot/local_fs/snapshot-restore-001/_restore?pretty" -d '{
      "indices": "logs-2026.04",
      "include_global_state": false
    }'
    {
      "accepted" : true
    }

    Leaving include_global_state at true can roll back persistent cluster settings, templates, ingest pipelines, and other stack metadata that may affect unrelated workloads.

  6. Monitor shard recovery until the restore stage reaches done.
    $ curl -sS --fail "http://localhost:9200/_cat/recovery/logs-2026.04?v&h=index,shard,type,stage,repository,snapshot,files_percent,bytes_percent"
    index        shard type     stage repository snapshot             files_percent bytes_percent
    logs-2026.04 0     snapshot done  local_fs   snapshot-restore-001 100.0%        100.0%

    The CAT recovery API is convenient for operator checks. For automation or deeper detail, use the index recovery API at GET /logs-2026.04/_recovery.

  7. Check that the restored index is open.
    $ curl -sS --fail "http://localhost:9200/_cat/indices/logs-2026.04?v&h=health,status,index,pri,rep,docs.count"
    health status index        pri rep docs.count
    green  open   logs-2026.04   1   0          1

    Elasticsearch opens restored indices automatically when recovery succeeds, so a separate _open request is not required in the normal flow.

  8. Count the restored documents.
    $ curl -sS --fail "http://localhost:9200/logs-2026.04/_count?pretty"
    {
      "count" : 1,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      }
    }

    A count of 1 matches the snapshot-era data in this example and confirms the restored index is searchable.