Skip to content

REST API

AOSC exposes REST endpoints under /_plugins/_aosc.

Start Migration

text
POST /_plugins/_aosc/{index}/_start

index is the source index name. The request body names the pre-created target index and the alias to swap at cutover.

Request Body

FieldTypeRequiredDescription
target_indexstringYesExisting target index.
aliasstringYesAlias currently used for the source and moved to the target at cutover.
transform_scriptobjectNoInline or stored Painless update script. Omit for identity.
optionsobjectNoPer-migration overrides.

transform_script fields:

FieldTypeRequiredDescription
typestringYesinline or stored.
sourcestringFor inlinePainless source.
idstringFor storedStored script ID.
paramsobjectNoScript parameters.
script_contextstringNoDefaults to update. Only update is supported by the base plugin.

options fields:

FieldDefaultDescription
convergence_threshold_per_shardcluster default, currently 500Remaining ops threshold before a shard is considered converged.
max_convergence_rounds_per_shardcluster default, currently 1000Replay/convergence round limit.
doc_count_tolerance0Accepted source/target document count difference at cutover.
validation_queryunsetQuery DSL used to filter source and target counts during validation.
accept_data_loss_if_custom_routing_is_usedfalseRequired for BULK_API routing topologies. In that mode, deletes are replayed without the original routing key and can miss custom-routed target documents.
target_ready_timeout_secondscluster default, currently 14400Target readiness timeout.
remove_source_write_block_on_successcluster default, currently falseRemove the source write block after successful cutover.
transient_target_settingscluster defaultTarget settings applied during migration and restored later.

Example

bash
curl -X POST 'http://localhost:9200/_plugins/_aosc/my-index-v1/_start' \
  -H 'Content-Type: application/json' \
  -d '{
    "target_index": "my-index-v2",
    "alias": "my-index",
    "transform_script": {
      "type": "inline",
      "source": "ctx._source.migrated = true"
    },
    "options": {
      "convergence_threshold_per_shard": 200
    }
  }'

Response:

json
{
  "migration_id": "my-index-v1__my-index-v2__1716700000000",
  "accepted": true
}

Get Migration Status

text
GET /_plugins/_aosc/{index}/_status

Returns the migration document for the source index. If no migration is found, the transport action returns a not-found error.

Example response excerpt for a completed migration. Real responses include one shards entry per source shard and can be large on high-shard indices.

json
{
  "migration_id": "21b526c5-4794-4a55-9186-2020f702a731",
  "source_index": "my-index-v1",
  "target_index": "my-index-v2",
  "alias": "my-index",
  "phase": "COMPLETED",
  "shard_routing_mode": "SAME_SHARD",
  "start_time_millis": 1780991529496,
  "last_updated_millis": 1781030665647,
  "options": {
    "convergence_threshold_per_shard": 1000,
    "max_convergence_rounds_per_shard": 1000,
    "doc_count_tolerance": 0,
    "target_ready_timeout_seconds": 14400,
    "remove_source_write_block_on_success": true
  },
  "cutover_context": {
    "source_doc_count": 689217412,
    "target_doc_count": 689217412,
    "doc_count_tolerance": 0,
    "doc_count_validation_passed": true,
    "alias_swap_succeeded": true,
    "cutover_start_millis": 1781030652331,
    "cutover_end_millis": 1781030665206
  },
  "shards": {
    "0": {
      "phase": "COMPLETED",
      "last_replayed_seq_no": 8453324,
      "target_seq_no": 8453324,
      "backfill_cutoff_seq_no": 8448260,
      "backfill": {
        "status": "COMPLETED",
        "documents_indexed": 1012245,
        "bulk_retries": 0,
        "rounds": 2025,
        "start_time_millis": 1781008395372,
        "end_time_millis": 1781010339131
      },
      "replay": {
        "status": "COMPLETED",
        "operations_applied": 415,
        "rounds": 1,
        "current_gap": 0
      },
      "convergence": {
        "status": "COMPLETED",
        "operations_applied": 4649,
        "rounds": 3978,
        "current_gap": 0
      },
      "catching_up": {
        "status": "COMPLETED",
        "operations_applied": 0,
        "rounds": 1,
        "current_gap": 0
      },
      "transition_history": [
        { "phase": "PENDING", "start_time_millis": 1780991529840, "end_time_millis": 1781008395135 },
        { "phase": "BACKFILLING", "start_time_millis": 1781008395372, "end_time_millis": 1781010339131 },
        { "phase": "COMPLETING", "start_time_millis": 1781030651618, "end_time_millis": 1781030651640 }
      ]
    }
  }
}

Common top-level fields:

FieldDescription
migration_idUnique migration identifier.
source_indexSource index name.
target_indexTarget index name.
aliasAlias used for cutover.
phaseCoordinator phase.
shard_routing_modeRouting strategy selected for shard movement, such as SAME_SHARD or SPLIT_SHARD.
optionsResolved migration options.
transform_scriptTransform script, if set.
shardsMap of shard ID to shard progress.
cutover_contextDocument-count validation and alias-swap details once cutover reaches completion.
transition_historyCoordinator phase transition history when present. Per-shard transition history is stored under each shard.
error_messageTop-level error on failure.

Cancel Migration

text
POST /_plugins/_aosc/{index}/_cancel

Response:

json
{
  "accepted": true,
  "phase": "CANCELLING"
}

Cancellation is asynchronous. Poll status until the coordinator reaches CANCELLED or FAILED.

List Migrations

text
GET /_plugins/_aosc/_list

Query parameters:

ParameterDefaultDescription
statusallComma-separated coordinator phases. The pseudo-token ACTIVE expands to all non-terminal phases.
size50Maximum number of results. Values above 500 are clamped.

Example:

bash
curl -s 'http://localhost:9200/_plugins/_aosc/_list?status=ACTIVE&size=100' | jq '.'

Response:

json
{
  "migrations": [
    {
      "migration_id": "my-index-v1__my-index-v2__1716700000000",
      "source_index": "my-index-v1",
      "target_index": "my-index-v2",
      "alias": "my-index",
      "phase": "COMPLETED",
      "shards_by_phase": { "COMPLETED": 5 },
      "shard_count": 5,
      "is_terminal": true,
      "elapsed_seconds": 142
    }
  ],
  "truncated": false,
  "active_count": 0
}

Cleanup Retention Leases

text
POST /_plugins/_aosc/_admin/_cleanup_leases

Query parameters:

ParameterDefaultDescription
indexunsetRestrict cleanup to one index. Omit to scan open indices.
dry_runtrueWhen true, list matching AOSC leases without removing them.

Examples:

bash
curl -X POST 'http://localhost:9200/_plugins/_aosc/_admin/_cleanup_leases'
curl -X POST 'http://localhost:9200/_plugins/_aosc/_admin/_cleanup_leases?index=my-index-v1&dry_run=false'

Only retention leases whose ID starts with aosc-migration- are considered.

Clear Cluster State

text
POST /_plugins/_aosc/_admin/_clear_state

Query parameters:

ParameterDefaultDescription
dry_runtruePreview what would be cleared.
try_closetrueTry to close in-memory coordinators on the cluster-manager node.
migration_idunsetClear only one migration. Omit to target all AOSC migration entries.
detailedfalseInclude detailed state in the response.

Examples:

bash
curl -X POST 'http://localhost:9200/_plugins/_aosc/_admin/_clear_state'
curl -X POST 'http://localhost:9200/_plugins/_aosc/_admin/_clear_state?dry_run=false'

Use this endpoint only after confirming that normal cancellation or failure cleanup cannot resolve the state.

Released under the Apache 2.0 License.