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
- Open the storage migration wizard (or use the CLI/REST equivalents below).
- Run a dry run first.
- Run the real migration in batches.
- Switch delivery to the destination profile only once you’re satisfied with the migration results.
wp universal-storage storage_migrate --source-profile=1 --dest-profile=2 --dry-runVerify 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.