Skip to content

Latest commit

 

History

History
870 lines (719 loc) · 28.1 KB

File metadata and controls

870 lines (719 loc) · 28.1 KB

RabbitMQ Queue Migration Plugin - HTTP API Reference

Complete reference for the Queue Migration Plugin HTTP API endpoints.

Base URL

All endpoints are prefixed with /api/queue-migration/ and require authentication.

Example:

http://localhost:15672/api/queue-migration/status

Authentication

All endpoints require RabbitMQ user authentication. Use HTTP Basic Auth with management plugin credentials.

Example:

curl -u guest:guest http://localhost:15672/api/queue-migration/status

URL Encoding

Virtual host names and migration IDs must be URL-encoded when used in URL paths. This includes:

  • /%2F
  • &%26
  • #%23
  • Unicode characters (e.g., ü%C3%BC, 日本語%E6%97%A5%E6%9C%AC%E8%AA%9E)

Examples:

# Vhost "/" (default)
curl -u guest:guest http://localhost:15672/api/queue-migration/start/%2F

# Vhost "/test&foo"
curl -u guest:guest http://localhost:15672/api/queue-migration/start/%2Ftest%26foo

# Vhost "/test/über&co" (with unicode)
curl -u guest:guest http://localhost:15672/api/queue-migration/start/%2Ftest%2F%C3%BCber%26co

# Vhost "/test/日本語&queue" (with CJK characters)
curl -u guest:guest -X POST http://localhost:15672/api/queue-migration/check/%2Ftest%2F%E6%97%A5%E6%9C%AC%E8%AA%9E%26queue

Plugin Initialization States

The plugin sets up its Mnesia tables asynchronously when the broker starts. Until that setup completes, every endpoint listed below returns 503 Service Unavailable with a JSON body identifying the plugin's init state. Callers must be prepared to handle 503 from any endpoint, including the status endpoints, until the plugin reports ready.

503 body while the plugin is initialising

{
  "status": "initializing",
  "attempts": 3,
  "max_attempts": 10,
  "started_at": "2026-06-05T17:55:00Z"
}

The plugin is still attempting to set up its tables. The retry budget is 10 attempts of 30 seconds each (5 minutes total). Subsequent requests may succeed once the plugin transitions to ready. Callers can poll any endpoint until they receive a 2xx response.

503 body when the plugin failed to initialise

{
  "status": "failed",
  "attempts": 10,
  "max_attempts": 10,
  "started_at": "2026-06-05T17:55:00Z",
  "failed_at": "2026-06-05T18:00:00Z",
  "error": "{timeout_waiting_for_tables, [...], [queue_migration, queue_migration_status]}"
}

The plugin exhausted its retry budget. The plugin's HTTP API will continue to return 503 until an operator runs rabbitmq-plugins disable rabbitmq_queue_migration followed by rabbitmq-plugins enable rabbitmq_queue_migration on each broker node.


Endpoints

Start Migration

Start migration for all eligible queues on a vhost.

Endpoints:

POST /api/queue-migration/start
POST /api/queue-migration/start/:vhost

Parameters:

  • :vhost - Virtual host name (URL-encoded). Must be specified in the URL path.

Important: The vhost must be specified in the URL, not in the request body. The /api/queue-migration/start endpoint (without a vhost path parameter) defaults to the / vhost. To migrate a different vhost, you must use /api/queue-migration/start/:vhost with the vhost name URL-encoded in the path.

Request Body (optional):

{
  "skip_unsuitable_queues": true,
  "tolerance": 10.0,
  "batch_size": 10,
  "batch_order": "smallest_first",
  "allow_message_ttl": false,
  "set_default_queue_type": "quorum"
}

Request Body Fields:

  • skip_unsuitable_queues (optional, boolean) - When true, skip queues that fail validation checks instead of blocking the entire migration. Defaults to false.
  • tolerance (optional, number) - Message count tolerance percentage (0.0-100.0) for per-queue verification. A queue passes verification if the destination message count is within this percentage of the source count. Use this when publishers set per-message TTL that may cause messages to expire during migration. When unset, the configured defaults apply: 5.0% over-delivery and 0.0% under-delivery (exact match for lost messages).
  • batch_size (optional, integer or "all") - Number of queues to migrate in this batch. Use 0 or "all" to migrate all eligible queues. Defaults to all. Ignored if queue_names is specified.
  • batch_order (optional, string) - Order to select queues for batching: "smallest_first" or "largest_first". Defaults to "smallest_first". Ignored if queue_names is specified.
  • queue_names (optional, array of strings) - Specific queue names to migrate. When provided, only these queues are migrated. Takes precedence over batch_size and batch_order. Non-existent or ineligible queues are logged and skipped.
  • allow_message_ttl (optional, boolean) - When true, queues that have a queue-level message TTL (the x-message-ttl queue argument or the message-ttl policy key) are allowed to migrate instead of being treated as unsuitable. Defaults to false. This forces the message count tolerance to 100% in both directions (overriding any tolerance value supplied), because opting in means accepting that any or all messages in these queues may expire during migration. Note that tolerance is migration-wide, so enabling this disables message-count verification for every queue in the run, not only the queues with a message TTL. The migrated quorum queue retains its x-message-ttl argument.
  • set_default_queue_type (optional, string) - When set to "quorum" or "classic", the virtual host's default queue type is set to that value after the migration completes successfully. Any other value is rejected. When unset, the vhost default queue type is left unchanged. This is useful after migrating to quorum so that clients which declare queues without an explicit x-queue-type (relying on the vhost default) resolve to the migrated queue type instead of failing redeclaration. It overwrites any existing default queue type, and only affects newly declared or redeclared queues, not existing ones. Setting the default is best-effort: if it fails, the failure is logged but the migration is still reported as successful.

Request:

# Default vhost (/)
curl -u guest:guest -X POST http://localhost:15672/api/queue-migration/start

# Specific vhost - vhost MUST be in the URL path, not the body
curl -u guest:guest -X POST http://localhost:15672/api/queue-migration/start/my-vhost

# Vhost with special characters (e.g., /production/app)
curl -u guest:guest -X POST http://localhost:15672/api/queue-migration/start/%2Fproduction%2Fapp

# Skip unsuitable queues
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"skip_unsuitable_queues": true}' \
  http://localhost:15672/api/queue-migration/start/%2F

# Migrate only 10 queues, smallest first
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"batch_size": 10, "batch_order": "smallest_first"}' \
  http://localhost:15672/api/queue-migration/start/%2Fmy-vhost

# Migrate all remaining queues (batch_size=0 means "all")
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"batch_size": 0}' \
  http://localhost:15672/api/queue-migration/start/%2Fmy-vhost

# Migrate specific queues by name
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"queue_names": ["queue1", "queue2", "queue3"]}' \
  http://localhost:15672/api/queue-migration/start/%2Fmy-vhost

# Migrate specific queues (queue_names takes precedence over batch_size)
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"queue_names": ["queue1", "queue2"], "batch_size": 10}' \
  http://localhost:15672/api/queue-migration/start/%2Fmy-vhost

# Allow message count tolerance for queues with per-message TTL
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"tolerance": 10.0}' \
  http://localhost:15672/api/queue-migration/start/%2F

# Allow queues with a queue-level message TTL to migrate (forces tolerance to 100%)
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"allow_message_ttl": true}' \
  http://localhost:15672/api/queue-migration/start/%2F

# Set the vhost default queue type to quorum after a successful migration
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"set_default_queue_type": "quorum"}' \
  http://localhost:15672/api/queue-migration/start/%2F

Common Mistake: Do not pass "vhost" in the JSON body - it will be ignored. The vhost is always read from the URL path.

Response (200 OK):

{
  "migration_id": "ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz",
  "status": "started"
}

Response Fields:

  • migration_id - Base64url-encoded unique migration identifier. Use this ID to track the migration via the status endpoint.
  • status - Request status (started)

Note: The migration runs asynchronously. Use the returned migration_id with the /api/queue-migration/status/:migration_id endpoint to monitor progress.

Error Responses:

400 Bad Request - Validation failed or invalid parameters:

Invalid option value (any request body option that is present but has an invalid value is rejected; the option is not silently ignored):

{
  "error": "bad_request",
  "reason": "Invalid value for option 'allow_message_ttl': must be a boolean"
}

Shovel plugin not enabled:

{
  "error": "bad_request",
  "reason": "rabbitmq_shovel plugin must be enabled for migration. Enable the plugin with: rabbitmq-plugins enable rabbitmq_shovel"
}

Unsuitable queues found (when skip mode not enabled):

{
  "error": "bad_request",
  "reason": "Found 5 queue(s) with issues (too many messages, too many bytes, or unsuitable arguments)",
  "problematic_queue_count": 5
}

Insufficient disk space:

{
  "error": "bad_request",
  "reason": "Insufficient disk space for migration. Required: 5000MB, Available: 2000MB"
}

Queue leaders imbalanced:

{
  "error": "bad_request",
  "reason": "Queue leaders are imbalanced. Re-balance queue leaders before migration."
}

Get Migration Status

Get overall migration status and list of all migrations.

Endpoint:

GET /api/queue-migration/status

Request:

curl -u guest:guest http://localhost:15672/api/queue-migration/status

Response (200 OK):

{
  "status": "in_progress",
  "migrations": [
    {
      "id": "ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz",
      "display_id": "/ (2025-12-21 10:30:00) on rabbit@node1",
      "vhost": "/",
      "started_at": "2025-12-21 10:30:00",
      "completed_at": null,
      "total_queues": 10,
      "completed_queues": 5,
      "skipped_queues": 0,
      "progress_percentage": 50,
      "status": "in_progress",
      "skip_unsuitable_queues": false,
      "tolerance": 10.0,
      "error": null
    },
    {
      "id": "...",
      "display_id": "/ (2025-12-20 15:00:00) on rabbit@node1",
      "vhost": "/",
      "started_at": "2025-12-20 15:00:00",
      "completed_at": "2025-12-20 15:05:30",
      "total_queues": 20,
      "completed_queues": 20,
      "skipped_queues": 0,
      "progress_percentage": 100,
      "status": "completed",
      "skip_unsuitable_queues": false,
      "tolerance": null,
      "error": null
    }
  ]
}

Response Fields:

  • status - Overall system status:
    • not_running - No active migration
    • in_progress - Migration currently running
  • migrations - Array of migration records (most recent first)

Migration Record Fields:

  • id - Base64url-encoded migration identifier
  • display_id - Human-readable identifier with vhost, timestamp, and node
  • vhost - Virtual host
  • started_at - Start timestamp (YYYY-MM-DD HH:MM:SS format, UTC)
  • completed_at - Completion timestamp (null if in progress)
  • total_queues - Total queues to migrate
  • completed_queues - Queues completed so far
  • skipped_queues - Queues skipped
  • progress_percentage - Progress (0-100)
  • status - Migration status:
    • pending - Not started yet
    • in_progress - Currently migrating
    • completed - Successfully completed
    • failed - Migration failed
    • interrupted - Migration was interrupted
    • rollback_pending - Requires rollback
    • rollback_completed - Rollback completed
  • skip_unsuitable_queues - Whether skip mode was enabled
  • tolerance - Message count tolerance percentage (null if not set). A migration started with allow_message_ttl: true reports tolerance as 100.0, since that option forces the tolerance. The allow_message_ttl option itself is not persisted and is not reported in status.
  • error - Error details (null if no error)

Get Detailed Migration Status

Get detailed status for a specific migration including per-queue information.

Endpoint:

GET /api/queue-migration/status/:migration_id

Parameters:

  • :migration_id - Base64url-encoded migration identifier (URL-encoded)

Request:

curl -u guest:guest \
  http://localhost:15672/api/queue-migration/status/ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz

Response (200 OK):

{
  "migration": {
    "id": "ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz",
    "display_id": "/ (2025-12-21 10:30:00) on rabbit@node1",
    "vhost": "/",
    "started_at": "2025-12-21 10:30:00",
    "completed_at": null,
    "total_queues": 10,
    "completed_queues": 5,
    "skipped_queues": 0,
    "progress_percentage": 50,
    "status": "in_progress",
    "skip_unsuitable_queues": false,
    "tolerance": 10.0,
    "error": null,
    "snapshots": []
  },
  "queues": [
    {
      "resource": {
        "name": "my-queue",
        "vhost": "/"
      },
      "status": "completed",
      "started_at": "2025-12-21 10:30:05",
      "completed_at": "2025-12-21 10:30:15",
      "total_messages": 1000,
      "migrated_messages": 1000,
      "progress_percentage": 100,
      "error": null
    },
    {
      "resource": {
        "name": "another-queue",
        "vhost": "/"
      },
      "status": "in_progress",
      "started_at": "2025-12-21 10:30:20",
      "completed_at": null,
      "total_messages": 5000,
      "migrated_messages": 2500,
      "progress_percentage": 50,
      "error": null
    }
  ]
}

Response Fields:

  • migration - Migration record (same as status list)
  • queues - Array of per-queue status records

Queue Status Fields:

  • resource - Queue resource object:
    • name - Queue name
    • vhost - Virtual host
  • status - Queue migration status:
    • pending - Not started yet
    • in_progress - Currently migrating
    • completed - Successfully migrated
    • failed - Migration failed
    • skipped - Skipped due to validation issues (when skip_unsuitable_queues is enabled)
    • rollback_completed - Rollback completed
  • started_at - Queue migration start timestamp
  • completed_at - Queue migration completion timestamp (null if in progress)
  • total_messages - Total messages in queue at start
  • migrated_messages - Messages migrated so far
  • progress_percentage - Queue progress (0-100)
  • error - Error details (if status is failed) or skip reason (if status is skipped)

Error Response (404 Not Found):

Returned when the migration ID is invalid (cannot be decoded) or the migration does not exist.

{
  "error": "Migration not found"
}

Interrupt Migration

Interrupt a running migration. In-flight queue migrations complete gracefully while remaining queues are skipped.

Endpoint:

POST /api/queue-migration/interrupt/:migration_id

Parameters:

  • :migration_id - Migration ID (URL-encoded)

Request:

curl -u guest:guest -X POST \
  http://localhost:15672/api/queue-migration/interrupt/g2gCbQAAAA5yYWJiaXRAcm1xMGIAAAPoAAAAAAA=

Success Response (200 OK):

{
  "interrupted": true,
  "migration_id": "g2gCbQAAAA5yYWJiaXRAcm1xMGIAAAPoAAAAAAA="
}

Behavior:

  • Sets migration status to interrupted
  • Workers check status before processing each queue
  • Queues already being migrated complete normally
  • Remaining queues are skipped and marked with status skipped
  • Post-migration restore runs normally (listeners resumed, snapshots cleaned up)
  • Migration completes with status interrupted and partial queue count

Error Response (404 Not Found):

Returned when the migration ID is invalid or the migration does not exist.

{
  "error": "Migration not found"
}

Check Compatibility

Check if queues are eligible for migration and validate system readiness.

Endpoint:

POST /api/queue-migration/check/:vhost

Parameters:

  • :vhost - Virtual host name (URL-encoded). Must be specified in the URL path. Use all to check all vhosts.

Important: Unlike the start endpoint, there is no default vhost for the check endpoint. You must always specify the vhost in the URL path.

Request Body (optional):

{
  "skip_unsuitable_queues": true,
  "allow_message_ttl": false
}

Request Body Fields:

The check endpoint accepts the same request body options as the start endpoints (skip_unsuitable_queues, tolerance, batch_size, batch_order, queue_names, allow_message_ttl, set_default_queue_type) and validates them the same way (an invalid option value returns 400, see below). This is deliberate: a compatibility check passes or fails exactly as the actual migration would for the same options. Note that set_default_queue_type has no effect on a check, since a check does not modify the vhost. The options most relevant to a check are:

  • skip_unsuitable_queues (optional, boolean) - When true, unsuitable queues are shown as informational and don't affect overall readiness. Defaults to false.
  • allow_message_ttl (optional, boolean) - When true, queues with a queue-level message TTL are reported as suitable rather than unsuitable, matching how a migration started with the same option would treat them. Defaults to false.

Request:

# Check the default vhost (/)
curl -u guest:guest -X POST \
  http://localhost:15672/api/queue-migration/check/%2F

# Check a specific vhost (e.g., /production/app)
curl -u guest:guest -X POST \
  http://localhost:15672/api/queue-migration/check/%2Fproduction%2Fapp

# Check all vhosts
curl -u guest:guest -X POST \
  http://localhost:15672/api/queue-migration/check/all

# With skip mode enabled
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"skip_unsuitable_queues": true}' \
  http://localhost:15672/api/queue-migration/check/%2F

# Check as a message-TTL-allowing migration would (queues with x-message-ttl reported suitable)
curl -u guest:guest -X POST \
  -H "Content-Type: application/json" \
  -d '{"allow_message_ttl": true}' \
  http://localhost:15672/api/queue-migration/check/%2F

Response (200 OK) - single vhost:

{
  "vhost": "/",
  "skip_unsuitable_queues": false,
  "overall_ready": true,
  "queue_checks": {
    "summary": {
      "total_queues": 10,
      "unsuitable_queues": 0,
      "compatibility_percentage": 100,
      "compatible_queues": 10
    },
    "results": []
  },
  "system_checks": {
    "all_passed": true,
    "checks": [
      {
        "check_type": "relaxed_checks_setting",
        "status": "passed",
        "message": "Relaxed checks setting is enabled"
      },
      {
        "check_type": "leader_balance",
        "status": "passed",
        "message": "Queue leaders are balanced across cluster nodes"
      },
      {
        "check_type": "queue_synchronization",
        "status": "passed",
        "message": "All mirrored classic queues are fully synchronized"
      },
      {
        "check_type": "queue_suitability",
        "status": "passed",
        "message": "All queues are suitable for migration"
      },
      {
        "check_type": "disk_space",
        "status": "passed",
        "message": "Sufficient disk space available for migration"
      },
      {
        "check_type": "active_alarms",
        "status": "passed",
        "message": "No active alarms"
      },
      {
        "check_type": "memory_usage",
        "status": "passed",
        "message": "Memory usage is within acceptable limits"
      },
      {
        "check_type": "snapshot_not_in_progress",
        "status": "passed",
        "message": "No EBS snapshots in progress"
      }
    ]
  }
}

Response Fields:

  • vhost - Virtual host being checked
  • skip_unsuitable_queues - Whether skip mode was requested
  • overall_ready - Boolean indicating if migration can proceed
  • queue_checks - Queue-level validation results
    • summary - Aggregate queue statistics
    • results - Array of individual queue issues (empty when all compatible)
  • system_checks - System-level validation results
    • all_passed - Boolean indicating all system checks passed
    • checks - Array of individual check results

System Check Types:

  • relaxed_checks_setting - Relaxed argument checks enabled
  • leader_balance - Queue leaders balanced across nodes
  • queue_synchronization - All mirrored queues synchronized
  • queue_suitability - All queues suitable for migration
  • disk_space - Sufficient disk space available
  • active_alarms - No active memory or disk alarms
  • memory_usage - Memory usage within configured threshold
  • snapshot_not_in_progress - No EBS snapshots currently in progress

Response (200 OK) - all vhosts (/api/queue-migration/check/all):

{
  "vhost": "all",
  "vhost_results": [
    {
      "vhost": "/",
      "overall_ready": true,
      "skip_unsuitable_queues": false,
      "system_checks": { "..." : "..." },
      "queue_checks": { "..." : "..." }
    },
    {
      "vhost": "/production",
      "overall_ready": false,
      "skip_unsuitable_queues": false,
      "system_checks": { "..." : "..." },
      "queue_checks": { "..." : "..." }
    }
  ]
}

Each entry in vhost_results has the same shape as the single-vhost response.


Get Rollback Pending Migration

Get the most recent migration in rollback_pending state.

Endpoint:

GET /api/queue-migration/rollback-pending

Request:

curl -u guest:guest http://localhost:15672/api/queue-migration/rollback-pending

Response (200 OK):

{
  "id": "ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz",
  "display_id": "/ (2025-12-21 10:30:00) on rabbit@node1",
  "vhost": "/",
  "status": "rollback_pending",
  "started_at": "2025-12-21 10:30:00",
  "completed_at": "2025-12-21 10:35:00",
  "total_queues": 10,
  "completed_queues": 8,
  "progress_percentage": 80,
  "snapshots": [
    {
      "node": "rabbit@node1",
      "instance_id": "i-0abc1234567890001",
      "snapshot_id": "snap-0abc123",
      "volume_id": "vol-0def456"
    },
    {
      "node": "rabbit@node2",
      "instance_id": "i-0abc1234567890002",
      "snapshot_id": "snap-0ghi789",
      "volume_id": "vol-0jkl012"
    },
    {
      "node": "rabbit@node3",
      "instance_id": "i-0abc1234567890003",
      "snapshot_id": "snap-0mno345",
      "volume_id": "vol-0pqr678"
    }
  ]
}

Response Fields:

  • Standard migration fields (id, vhost, status, etc.)
  • snapshots - Array of snapshot information for rollback:
    • node - RabbitMQ node name
    • instance_id - EC2 instance ID
    • snapshot_id - EBS snapshot ID or tar file path
    • volume_id - EBS volume ID or tar file path

Error Response (404 Not Found):

{
  "error": "No rollback pending migration found"
}

Use Case: This endpoint is used by automated rollback systems to retrieve snapshot information for restoring the cluster after a failed migration.


Status Codes

Code Meaning Description
200 OK Request successful
400 Bad Request Invalid parameters or validation failed
401 Unauthorized Authentication required
404 Not Found Resource not found (migration ID or vhost)
500 Internal Server Error Server error during processing
503 Service Unavailable Plugin is still initialising or in failed state. See Plugin Initialization States.

Migration ID Format

Migration IDs are base64url-encoded Erlang terms. Each ID encodes a 2-tuple of:

  • Timestamp - milliseconds since the epoch (erlang:system_time(millisecond))
  • Node name - the Erlang node atom on which the migration was started (node())

Source: rqm_util:generate_migration_id/0 and rqm_util:format_migration_id/1.

Example:

ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz

URL Encoding: When using migration IDs in URLs, ensure proper URL encoding of special characters.

Polling Recommendations

When monitoring migration progress:

  • Poll interval: 5-10 seconds recommended
  • Timeout: Set based on queue count and message volume
  • Exponential backoff: Consider for long-running migrations

Example monitoring script:

#!/bin/bash

MIGRATION_ID="$1"
INTERVAL=5

while true; do
  STATUS=$(curl -s -u guest:guest \
    "http://localhost:15672/api/queue-migration/status/$MIGRATION_ID" \
    | jq -r '.migration.status')

  if [ "$STATUS" = "completed" ]; then
    echo "Migration completed successfully"
    exit 0
  elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "rollback_pending" ]; then
    echo "Migration failed: $STATUS"
    exit 1
  fi

  PROGRESS=$(curl -s -u guest:guest \
    "http://localhost:15672/api/queue-migration/status/$MIGRATION_ID" \
    | jq -r '.migration.progress_percentage')

  echo "Progress: $PROGRESS%"
  sleep $INTERVAL
done

Error Handling

Error Scenarios

Plugin Initialising or Init Failed:

A 503 Service Unavailable response from any endpoint carries a JSON body whose status field is either initializing or failed. See Plugin Initialization States for the full body shape and recovery procedure.

Migration Already Running:

{
  "error": "bad_request",
  "reason": "Migration validation failed: in_progress"
}

Action: Wait for current migration to complete or check its status.

Validation Failed:

{
  "error": "bad_request",
  "reason": "rabbitmq_shovel plugin must be enabled for migration. Enable the plugin with: rabbitmq-plugins enable rabbitmq_shovel"
}

Action: Fix the validation issue and retry. Use the compatibility endpoint for detailed validation results.

No Eligible Queues:

{
  "error": "bad_request",
  "reason": "No mirrored classic queues found in this vhost. Only classic queues with an HA policy can be migrated.",
  "total_queues": 0,
  "unsuitable_queues": 0
}

Action: Verify queues are mirrored classic queues with HA policies applied.

Insufficient Disk Space:

{
  "error": "bad_request",
  "reason": "Insufficient disk space for migration. Required: 5000MB, Available: 2000MB",
  "required_free_mb": 5000,
  "available_for_migration_mb": 2000
}

Action: Free up disk space or reduce queue message counts before migrating.

Examples

Complete Migration Workflow

#!/bin/bash

# 1. Check compatibility
echo "Checking compatibility..."
curl -s -u guest:guest -X POST http://localhost:15672/api/queue-migration/check/%2F | jq

# 2. Start migration
echo "Starting migration..."
RESPONSE=$(curl -s -u guest:guest -X POST http://localhost:15672/api/queue-migration/start)
MIGRATION_ID=$(echo "$RESPONSE" | jq -r '.migration_id')
echo "Migration started: $MIGRATION_ID"

# 3. Monitor progress
echo "Monitoring progress..."
while true; do
  STATUS=$(curl -s -u guest:guest \
    "http://localhost:15672/api/queue-migration/status/$MIGRATION_ID" \
    | jq -r '.migration.status')

  if [ "$STATUS" = "completed" ]; then
    echo "✅ Migration completed successfully"
    break
  elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "rollback_pending" ]; then
    echo "❌ Migration failed: $STATUS"
    exit 1
  fi

  PROGRESS=$(curl -s -u guest:guest \
    "http://localhost:15672/api/queue-migration/status/$MIGRATION_ID" \
    | jq -r '.migration.progress_percentage')

  echo "Progress: $PROGRESS%"
  sleep 5
done

# 4. Get detailed results
echo "Getting detailed results..."
curl -s -u guest:guest \
  "http://localhost:15672/api/queue-migration/status/$MIGRATION_ID" | jq

See Also