Skip to content

Cross-provider Migration

Move existing media between storage profiles — including between different providers entirely, such as Amazon S3 → Cloudflare R2 — using verify-before-switch safety: delivery only changes over to the new destination after it’s confirmed the migrated files are actually there.

Before you begin

Two configured storage profiles (source and destination) — see Storage Profiles.

Steps

  1. Open the storage migration wizard (or use the CLI/REST equivalents below).
  2. Run a dry run first.
  3. Run the real migration in batches.
  4. Switch delivery to the destination profile only once you’re satisfied with the migration results.
Terminal window
wp universal-storage storage_migrate --source-profile=1 --dest-profile=2 --dry-run

Verify it worked

Delivery URLs for migrated attachments resolve to the destination profile only after the explicit switch step — not automatically mid-migration. This means you can migrate at your own pace and confirm results before anything user-facing changes.

Troubleshooting

A migrated attachment still serves from the old profile — this is expected until you run the switch step; verify-before-switch means the old delivery path stays authoritative until you confirm the new one. After a successful switch, the destination profile’s PRESENT inventory row becomes the authoritative location for normal delivery, restore, verification, and private URL generation. The source location may remain represented as stale for historical or cleanup visibility, but STALE rows are not a normal automatic read fallback. If no valid PRESENT location can be established, KAZCODE fails safely and surfaces the reconciliation problem instead of selecting an arbitrary historical row.