How to Reindex OpenSearch Data for a Newer Version

Validated on 6 May 2026 • Last edited on 14 May 2026

OpenSearch is an open-source search and analytics suite which serves as a centralized location to manage logs forwarded from other resources, such as databases and Droplets.

OpenSearch enforces compatibility rules between the engine version and the version each index was created on. Before upgrading a managed OpenSearch cluster across a major version, reindex any indices created on an incompatible earlier version into new indices on the same cluster.

If you’re migrating from Elasticsearch to DigitalOcean OpenSearch, follow How to Migrate Elasticsearch Databases to DigitalOcean OpenSearch.

Why Reindexing Is Required

OpenSearch upgrades fail when the cluster contains indices created on versions older than the target version supports. Reindexing rebuilds the index using the current engine version, allowing the upgrade to proceed. Reindexing is also useful when you need to change mappings, the number of primary shards, or other static index settings that you cannot edit in place.

Prerequisites

Before you begin, make sure you have:

  • curl and jq installed locally
  • A healthy OpenSearch cluster you can pause or reroute writes on during reindexing
  • Enough storage on the cluster to hold both the source and destination indices, plus headroom for merges
  • The cluster’s connection details and CA certificate

Step 1: Identify Indices That Require Reindexing

Each index records the OpenSearch version it was created on. List those versions to identify indices that violate the target upgrade’s compatibility requirements:

curl -s -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/_all/_settings?filter_path=*.settings.index.version.created_string,*.settings.index.creation_date_string&human=true" | jq .

Replace <password> and <hostname> with values from your cluster’s connection details.

Use created_string to identify indices created on older major versions, especially indices that have passed through multiple upgrades. Skip internal indices (typically those starting with a dot) unless you have a specific reason to reindex them.

When upgrading across major versions, also review affected indices for deprecated mappings, removed analyzers, or unsupported plugins.

While identifying indices, record each index’s document count so you can verify the reindex operation later:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/_cat/indices?v&h=index,docs.count,pri.store.size,store.size"

pri.store.size reports the size of primary shards only. store.size includes both primary and replica shards.

Step 2: Choose a Reindexing Strategy

Reindexing always writes to a new index. Choose how clients transition to the new index after the data is copied:

  • Alias swap (recommended): Application traffic targets an alias. Reindex into a new index, then atomically repoint the alias to the new index. This approach minimizes risk and simplifies rollback.
  • Rename: Pause writes, reindex into a temporary index, delete the original index, recreate the original index name on the current version, then reindex the data back. Use this approach only when changing the application’s index target is not an option and you do not already use aliases.

The rest of this guide uses the alias swap approach. The reindexing steps are the same for a rename workflow, and only the cutover process differs.

Step 3: Check Disk Capacity

Reindexing temporarily stores two copies of the data on the same cluster. If a node reaches the flood-stage disk watermark, OpenSearch blocks all writes, including _reindex.

curl -s -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/_cat/allocation?v&s=disk.avail:asc"

Review:

  • disk.avail
  • disk.percent
  • disk.indices

Confirm the cluster has enough space for the new index, plus headroom for merges and temporary segments. If not, resize the cluster before continuing.

Warning
Avoid starting large reindex jobs when disk usage is already high (for example, above 70%). Reindexing creates new segments before old segments are removed, which can cause a temporary spike in storage usage.

To review the effective disk watermark settings:

curl -s -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/_cluster/settings?include_defaults=true" | jq '
  .defaults.cluster.routing.allocation.disk.watermark,
  .persistent.cluster.routing.allocation.disk.watermark,
  .transient.cluster.routing.allocation.disk.watermark
'

Step 4: Export the Source Index Configuration

Reindexing does not preserve the source index’s settings or mappings. Export them so you can recreate the index intentionally:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/<old-index-name>" > index-config.json

Strip metadata that belongs only to the original index instance:

jq '.[keys[0]] | {
  settings: {
    index: (
      .settings.index | del(
        .uuid,
        .version,
        .creation_date,
        .provided_name,
        .creation_date_string
      )
    )
  },
  mappings: .mappings
}' index-config.json > new-index-config.json

Edit new-index-config.json if you need to change shard counts, analyzers, or mappings before recreating the index.

Step 5: (Optional) Make the Source Index Read-Only

Block writes to the source index during reindexing so document counts remain stable for verification:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X PUT "https://<hostname>:25060/<old-index-name>/_settings" \
  -H 'Content-Type: application/json' \
  -d '{"index.blocks.write": true}'
Warning
Applications trying to write to the source index receive a 403 Forbidden error until this setting is removed. Plan for a write pause or reroute traffic before enabling it.

Step 6: Create the New Index

Use the sanitized configuration to create the destination index:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X PUT "https://<hostname>:25060/<new-index-name>" \
  -H 'Content-Type: application/json' \
  -d @new-index-config.json

For large indices, temporarily disable refreshes to improve indexing throughput:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X PUT "https://<hostname>:25060/<new-index-name>/_settings" \
  -H 'Content-Type: application/json' \
  -d '{"index": {"refresh_interval": "-1"}}'

After reindexing completes, restore refresh_interval to a normal value (for example, 1s) or clear the setting so the index falls back to the cluster default:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X PUT "https://<hostname>:25060/<new-index-name>/_settings" \
  -H 'Content-Type: application/json' \
  -d '{"index": {"refresh_interval": null}}'

Step 7: Reindex the Data

Run _reindex on the same cluster. For large indices, run asynchronously to avoid request timeouts:

TASK_ID=$(curl -s \
  -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X POST "https://<hostname>:25060/_reindex?wait_for_completion=false&slices=auto" \
  -H 'Content-Type: application/json' \
  -d '{
    "source": {"index": "<old-index-name>"},
    "dest":   {"index": "<new-index-name>"}
  }' | jq -r '.task')
echo "Reindex task: $TASK_ID"
  • slices=auto parallelizes the reindex operation across shards.
  • Add "size": 1000 under source to reduce batch size when needed; omit size to use the default batch size.

Monitor progress:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/_tasks/$TASK_ID" | jq '.task.status'

The task disappears from _tasks after completion. For smaller indices, omit wait_for_completion=false to run the request synchronously.

Step 8: Verify Document Counts

Compare the document counts for the old and new indices:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/<old-index-name>/_count"

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  "https://<hostname>:25060/<new-index-name>/_count"

The counts should match. If they don’t, review the reindex task output or cluster logs, resolve the issue, and rerun the reindex operation.

Step 9: Cut Over to the New Index

If your application reads through an alias, atomically swap the alias to the new index:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X POST "https://<hostname>:25060/_aliases" \
  -H 'Content-Type: application/json' \
  -d '{
    "actions": [
      {"remove": {"index": "<old-index-name>", "alias": "<alias-name>"}},
      {"add":    {"index": "<new-index-name>", "alias": "<alias-name>"}}
    ]
  }'

After the new index is verified in production, delete the old index:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X DELETE "https://<hostname>:25060/<old-index-name>"

If you used the rename strategy, delete the original index after verifying the temporary copy, then reindex the temporary index back into the original name. Repeat verification, then remove the temporary index.

If you made the source index read-only earlier and plan to keep it, remove the write block:

curl -u doadmin:<password> \
  --cacert /path/to/ca-certificate.crt \
  -X PUT "https://<hostname>:25060/<old-index-name>/_settings" \
  -H 'Content-Type: application/json' \
  -d '{"index.blocks.write": null}'

Repeat Steps 4-9 for each index that requires reindexing. If you reindex multiple large indices in sequence, recheck disk capacity between runs.

Step 10: Upgrade the Cluster

After all incompatible indices are re-indexed, trigger the major version upgrade on the cluster’s Overview page in the DigitalOcean Control Panel, or using the API.

We can't find any results for your search.

Try using different keywords or simplifying your search terms.