S3 Migration
The S3 Migration tool copies a bucket — or a single prefix inside one — from any S3-compatible source into your Carolina Cloud bucket. The copy runs entirely on our infrastructure: you fill out a short form, hit Start migration, and close the tab. We’ll keep going overnight, across reconnects, and through the multi-terabyte mark without you doing anything else.
Where to find it
Section titled “Where to find it”Dashboard sidebar → Storage → Migrate.
What it copies
Section titled “What it copies”- Anything S3-compatible. AWS S3, Wasabi, Backblaze B2, Cloudflare R2, DigitalOcean Spaces, MinIO, self-hosted Ceph — if it speaks the S3 API, the tool can read from it.
- A whole bucket or a single prefix. Leave the source Prefix blank to copy the whole bucket. Set it to a folder (e.g.
experiments/2025/) to copy just that subtree. Set it to a single object key (e.g.report.pdf) to copy one file. - Up to one job at a time per account. The tool runs your migration on a dedicated worker; queueing a second one while the first is live returns a 409.
What it can’t copy (yet)
Section titled “What it can’t copy (yet)”- Objects in AWS Glacier / Deep Archive. Glacier objects need to be restored to standard S3 before they’re readable, and the tool doesn’t yet issue restore requests for you. If you try to migrate a bucket with Glacier objects mixed in, the copy will fail with
Object in GLACIER, restore first. For now: restore the objects via the AWS Console oraws s3api restore-object, wait for the restore window to open, then start the migration. First-class Glacier source support is on the roadmap. - Sources that aren’t S3-compatible. Google Cloud Storage’s native API, Azure Blob, and FTP/SFTP sources are not supported. (GCS has an S3 interop mode that does work; you’d use it via the custom-endpoint option.). FTP/SFTP sources will soon be available to migrate to a Carolina Cloud bucket.
Step-by-step
Section titled “Step-by-step”1. Pick the source provider
Section titled “1. Pick the source provider”The Provider dropdown has presets for the common cases — AWS S3 (eight regions), Wasabi (two regions), Backblaze B2. Pick the one that matches where your data lives now. Each preset fills in the endpoint URL and the region automatically.
If your source isn’t in the list, choose Custom endpoint… and fill in:
- Endpoint URL — e.g.
https://<accountid>.r2.cloudflarestorage.comfor Cloudflare R2,https://nyc3.digitaloceanspaces.comfor DigitalOcean Spaces, or your MinIO/Ceph hostname. - Region (optional) — required for AWS, Wasabi, Backblaze B2, and DigitalOcean Spaces, all of which sign requests with SigV4 and reject signatures from the wrong region. Leave blank for Cloudflare R2, MinIO, or anything else that accepts
us-east-1by default.
2. Enter source credentials
Section titled “2. Enter source credentials”- Access key and Secret key — a pair of S3 credentials with at least
s3:ListBucketands3:GetObjecton the source bucket. Read-only is sufficient. - Bucket — the source bucket name.
- Prefix (optional) — a folder (
photos/) or a single object key (report.pdf). Leave blank to copy the whole bucket.
The secret key is forwarded once to the worker that runs rclone copy, then discarded. It’s never written to the database, and the worker wipes its on-disk config when the job finishes.
3. Pick the destination
Section titled “3. Pick the destination”- Bucket — the Carolina Cloud bucket the files will land in. If you belong to an org with a provisioned bucket and you’re an admin or the org owner, both your personal bucket and the org bucket appear in the dropdown. See Who can migrate to the org bucket below.
- Prefix (optional) — auto-mirrors whatever you typed for the source prefix until you edit it. Files land at
<prefix>/...inside the destination bucket.
4. Start migration
Section titled “4. Start migration”Click Start migration. The button shows Validating source credentials… for a beat while we run a one-object preflight list against the source — this catches bad credentials, the wrong endpoint, a missing bucket, or an empty bucket/prefix before any worker is even involved.
If the preflight passes, the page swaps into the active-job view.
During a migration
Section titled “During a migration”The active-job card shows:
- Elapsed time — ticks live, second by second.
- Progress bar and percentage — based on bytes copied vs. the source bucket’s total size. The first sizing pass can take a minute or two on a large bucket; until it finishes, the bar is indeterminate and the label reads Calculating total size…
- Data copied — bytes moved out of total bytes.
- Files copied — file count moved out of total files.
- Recent activity — collapsible tail of the worker’s log, refreshing every 30 seconds.
You can close the tab. The migration keeps running. When you come back to the page later (even days later), it remembers your last-viewed job and picks back up where it left off.
Cancelling
Section titled “Cancelling”Hit Cancel migration to stop a job mid-flight. Anything already copied stays in your destination bucket — cancellation does not undo partial transfers.
When it finishes
Section titled “When it finishes”You’ll land on one of three terminal cards:
- Migration complete — green check. Shows total bytes/files copied and the wall-clock duration. Files are in your destination bucket and ready to use.
- Migration failed — red X. Shows the worker’s error message and exit code, plus the tail of the log so you can see what went wrong. Common causes: a transient source-side network error, a source object in Glacier, or a permission change on the source IAM key mid-job.
- Migration cancelled — neutral. Confirms how many bytes/files made it through before you hit cancel.
All three give you a Start another migration button to launch a fresh job.
Common errors
Section titled “Common errors”| Error | What it means | Fix |
|---|---|---|
| Source credentials rejected — InvalidAccessKeyId | The source provider doesn’t recognize the access key. | Most often a provider mismatch (e.g. AWS preset with Wasabi keys). Check the preset, then check for typos/whitespace. |
| Source credentials rejected — SignatureDoesNotMatch | Access key recognized; secret didn’t match. | Re-paste the secret. Make sure access key and secret are a matching pair. |
| Source credentials rejected — AccessDenied | Credentials valid but IAM policy doesn’t allow listing the bucket. | Grant s3:ListBucket and s3:GetObject on the source bucket to the IAM user. |
| Source bucket not found | No bucket by that name lives at that endpoint. | Check spelling. For AWS, make sure you’ve selected the bucket’s actual region. |
| No objects found at source bucket/prefix | The bucket and credentials work, but the prefix is empty. | Either pick a different prefix or leave it blank to copy the whole bucket. |
| AuthorizationHeaderMalformed — region ‘X’ is wrong; expecting ‘Y’ | The endpoint URL points at one AWS region but you signed for another. | Pick the matching AWS preset, or set the Region field under the custom endpoint option. |
| Object in GLACIER, restore first | One or more objects in the prefix are in Glacier / Deep Archive and aren’t readable until restored. | Issue a restore via the AWS Console or aws s3api restore-object, wait for it to complete (3–48h depending on tier), then re-run the migration. |
| You already have a migration in progress | A previous job is still active on your account. | Wait for it to finish, or cancel it. |
Performance
Section titled “Performance”Each migration runs with a fixed per-job bandwidth cap. That’s a deliberate ceiling so a single migration can’t starve other customer workloads sharing the worker. A 1 TiB bucket typically finishes in roughly 1.5 hours of wall-clock time, network and source-side throttling permitting. Bigger transfers (10 TiB+) are perfectly fine to leave running overnight or over the weekend. If you require an expediated transfer, please contact support@carolinacloud.io.
Security and privacy
Section titled “Security and privacy”- Source secrets are never persisted. They’re passed through to the worker for the duration of the job, then wiped from disk.
- The destination is always your Carolina Cloud bucket. Carolina Cloud does not migrate data into a third-party destination; the destination dropdown is restricted to the buckets you own or admin.
- The copy is server-to-server. Bytes flow directly from your source to Wasabi over the worker — they don’t traverse your laptop, and they don’t pass through your local internet connection.
Who can migrate to the org bucket
Section titled “Who can migrate to the org bucket”If your account is in an org and the org has a bucket provisioned, both your personal bucket and the org bucket show up in the destination dropdown. Only org admins (the owner and anyone the owner has promoted) can actually dispatch a migration into the org bucket. A regular member who picks the org bucket from the dropdown will get a 403 from the dispatch endpoint.
Members can always migrate into their own personal bucket — no admin role required.
See Organizations → Overview for the full breakdown of org roles.