Complete reference for the Queue Migration Plugin HTTP API endpoints.
All endpoints are prefixed with /api/queue-migration/ and require authentication.
Example:
http://localhost:15672/api/queue-migration/status
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/statusVirtual 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%26queueStart 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/startendpoint (without a vhost path parameter) defaults to the/vhost. To migrate a different vhost, you must use/api/queue-migration/start/:vhostwith 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"
}Request Body Fields:
skip_unsuitable_queues(optional, boolean) - Whentrue, skip queues that fail validation checks instead of blocking the entire migration. Defaults tofalse.tolerance(optional, number) - Message count tolerance percentage (0.0-100.0) for per-queue verification. When set, 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. Defaults to0.0(exact match required).batch_size(optional, integer or"all") - Number of queues to migrate in this batch. Use0or"all"to migrate all eligible queues. Defaults toall. Ignored ifqueue_namesis specified.batch_order(optional, string) - Order to select queues for batching:"smallest_first"or"largest_first". Defaults to"smallest_first". Ignored ifqueue_namesis specified.queue_names(optional, array of strings) - Specific queue names to migrate. When provided, only these queues are migrated. Takes precedence overbatch_sizeandbatch_order. Non-existent or ineligible queues are logged and skipped.
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/%2FCommon 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_idwith the/api/queue-migration/status/:migration_idendpoint to monitor progress.
Error Responses:
400 Bad Request - Validation failed or invalid parameters:
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 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/statusResponse (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 migrationin_progress- Migration currently running
migrations- Array of migration records (most recent first)
Migration Record Fields:
id- Base64url-encoded migration identifierdisplay_id- Human-readable identifier with vhost, timestamp, and nodevhost- Virtual hoststarted_at- Start timestamp (YYYY-MM-DD HH:MM:SS format, UTC)completed_at- Completion timestamp (null if in progress)total_queues- Total queues to migratecompleted_queues- Queues completed so farskipped_queues- Queues skippedprogress_percentage- Progress (0-100)status- Migration status (see values below)skip_unsuitable_queues- Whether skip mode was enabledtolerance- Message count tolerance percentage (null if not set)error- Error details (null if no error)pending- Not started yetin_progress- Currently migratingcompleted- Successfully completedfailed- Migration failedinterrupted- Migration was interruptedrollback_pending- Requires rollbackrollback_completed- Rollback completed
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/ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tzResponse (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 namevhost- Virtual host
status- Queue migration status:pending- Not started yetin_progress- Currently migratingcompleted- Successfully migratedfailed- Migration failedskipped- Skipped due to validation issues (whenskip_unsuitable_queuesis enabled)rollback_completed- Rollback completed
started_at- Queue migration start timestampcompleted_at- Queue migration completion timestamp (null if in progress)total_messages- Total messages in queue at startmigrated_messages- Messages migrated so farprogress_percentage- Queue progress (0-100)error- Error details (if status isfailed) or skip reason (if status isskipped)
Error Response (404 Not Found):
Returned when the migration ID is invalid (cannot be decoded) or the migration does not exist.
{
"error": "Object Not Found",
"reason": "Not Found"
}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
interruptedand partial queue count
Error Response (404 Not Found):
Returned when the migration ID is invalid or the migration does not exist.
{
"error": "Object Not Found",
"reason": "Not Found"
}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. Useallto 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
}Request Body Fields:
skip_unsuitable_queues(optional, boolean) - Whentrue, unsuitable queues are shown as informational and don't affect overall readiness. Defaults tofalse.
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
# 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/%2FResponse (200 OK):
{
"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": "snapshot_not_in_progress",
"status": "passed",
"message": "No EBS snapshots in progress"
}
]
}
}Response Fields:
vhost- Virtual host being checkedskip_unsuitable_queues- Whether skip mode was requestedoverall_ready- Boolean indicating if migration can proceedqueue_checks- Queue-level validation resultssummary- Aggregate queue statisticsresults- Array of individual queue issues (empty when all compatible)
system_checks- System-level validation resultsall_passed- Boolean indicating all system checks passedchecks- Array of individual check results
System Check Types:
relaxed_checks_setting- Relaxed argument checks enabledleader_balance- Queue leaders balanced across nodesqueue_synchronization- All mirrored queues synchronizedqueue_suitability- All queues suitable for migrationdisk_space- Sufficient disk space availablesnapshot_not_in_progress- No EBS snapshots currently in progress
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-pendingResponse (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",
"snapshot_id": "snap-0abc123",
"volume_id": "vol-0def456"
},
{
"node": "rabbit@node2",
"snapshot_id": "snap-0ghi789",
"volume_id": "vol-0jkl012"
},
{
"node": "rabbit@node3",
"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 namesnapshot_id- EBS snapshot ID or tar file pathvolume_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.
| 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) |
| 409 | Conflict | Migration already in progress |
| 500 | Internal Server Error | Server error during processing |
Migration IDs are base64url-encoded Erlang terms containing:
- Timestamp
- Node name
- Unique identifier
Example:
ZzJnQ2JnWUE4VTJOS0pzQmR4aHlZV0pwYVhRdE1VQlRSVUV0TTB4SE5VaFdTbFZYU2tz
URL Encoding: When using migration IDs in URLs, ensure proper URL encoding of special characters.
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
doneMigration Already Running:
{
"error": "Migration already in progress",
"current_migration_id": "..."
}Action: Wait for current migration to complete or check its status.
Validation Failed:
{
"error": "Pre-migration validation failed",
"details": {
"check": "shovel_plugin",
"reason": "rabbitmq_shovel plugin is not enabled"
}
}Action: Fix the validation issue and retry. Use the compatibility endpoint for detailed validation results.
No Eligible Queues:
{
"error": "No eligible queues found for migration",
"vhost": "/"
}Action: Verify queues are mirrored classic queues with HA policies applied.
Insufficient Disk Space:
{
"error": "Pre-migration validation failed",
"details": {
"check": "disk_space",
"reason": "Insufficient disk space",
"required_bytes": 10737418240,
"available_bytes": 5368709120
}
}Action: Free up disk space or reduce queue message counts before migrating.
- Run compatibility check - Validate system readiness
- Review eligible queues - Confirm expected queues will migrate
- Check disk space - Ensure sufficient space available
- Backup data - Create manual backups if needed
- Monitor progress - Poll status endpoint regularly
- Check logs - Watch RabbitMQ logs for errors
- Avoid changes - Don't modify queues during migration
- Be patient - Large migrations can take hours
- Validate results - Check all queues converted to quorum type
- Verify messages - Confirm message counts match
- Test applications - Ensure applications work with quorum queues
- Update configuration - Set default queue type to quorum
The API does not implement rate limiting, but be considerate:
- Status polling: 5-10 second intervals recommended
- Concurrent requests: Avoid excessive parallel requests
- Migration starts: Only one migration per vhost at a time
- Authentication required: All endpoints require valid RabbitMQ credentials
- Authorization: User must have monitoring permissions (or higher)
- Sensitive data: Migration IDs and snapshots may contain sensitive information
- Network security: Use HTTPS in production environments
#!/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- README - Plugin overview and quick start
- AGENTS - Technical architecture and implementation details
- test/integration/README - Integration testing guide