A batch runbook that works for any provider
A client changes host, or you take over a portfolio: the mailboxes must follow without anyone losing a message during DNS propagation. This guide assumes only two things: IMAP access to both servers and control of the domain's DNS zone. It depends on no panel and no brand.
The difficulty is not copying a message, it is forgetting nothing around it: the mailbox nobody listed, the forward that only exists in the old panel, the quota that is too tight on the target, the mail that keeps arriving at the old address because a resolver still caches the old MX. Hence a batch method: inventory, prepare one file, sync twice, count.
Moving away from Gmail or Microsoft 365, or from AWS WorkMail to a Mailcow server, has dedicated guides ("Migrating professional email: leaving Gmail and Microsoft 365" and "AWS WorkMail EOL: migrate to self-hosted Mailcow on VPS"). Here we cover the general case of a client portfolio.
The inventory, before touching anything
An IMAP migration moves messages and folders. Nothing else. Everything that lives beside them in the old panel must be listed before the first transfer, otherwise it silently disappears at cutover.
Ask the old provider for an export of the accounts, or read them from its interface, and consolidate them in one table per domain. Add a "real usage" column: a 40 GB mailbox that actually holds 5 GB changes the copy time and the quota to plan on the target. Add a "last access" column: a mailbox not opened for a year is either a ghost account to archive or a form address that still receives requests. That question goes to the client, not to you.
The client must validate the table before you go further. It is the only protection against the forgotten mailbox.
What the inventory must contain, mailbox by mailbox
- Mailboxes and quotas — address, allocated quota, space actually used, number of folders, to size the target.
- Aliases and forwards — every alias, every forward to an external address, every catch-all: IMAP does not carry them, they must be recreated by hand.
- Autoresponders and filters — automatic replies, server-side sorting rules, block lists: recreate them, or export them if the panel allows it.
- Devices and mail clients — phones, Outlook, Thunderbird, scanners and printers that send through SMTP: each one must point to the new server.
- Credentials — one password per mailbox, or an app password if two-factor authentication is on at the source.
- Contacts and calendars — outside the IMAP scope: export them separately and tell the client explicitly.
The TTL schedule, before the MX cutover
The TTL (time to live) of a DNS record says how long a resolver may keep it in cache. If the MX is set to 86,400 seconds, a sender can keep delivering to the old server for twenty-four hours after your change. Lowering the TTL only helps if you do it early enough: the lowered value itself must have expired from caches before the cutover.
Practical rule: read the current MX TTL, lower the record to 300 seconds at least one old-TTL period before the cutover (two or three days ahead if you do not know it), then change nothing else. On the day, you change the MX, run the delta pass, and the old server stays active. The TTL goes back up only once the double-reading period is over.
Plan the authentication records too: the new provider's SPF and DKIM key are published before the cutover, not after. Their definition is in "SPF, DKIM, DMARC: passing the 5,000-email threshold".
Typical cutover schedule
Scroll the table
| When | Action | Why |
|---|---|---|
| D-7 | Inventory validated by the client, mailboxes created on the target | No forgotten mailbox, quotas sized |
| D-3 | MX TTL lowered to 300 seconds | The lowered value must expire from caches before D |
| D-2 | First imapsync pass, the bulk of the mail | The large volume is copied without urgency |
| D-1 | New provider's SPF and DKIM published | The first outgoing messages are authenticated |
| D | MX cutover, then delta pass | Picks up what arrived since the first pass |
| D+1 to D+3 | Extra delta passes, double reading | Late resolvers and queued mail |
| D+7 | Final check, TTL raised, old service cancelled | Cancel only after counting |
Credentials must not linger
A batch of mailboxes is a list of passwords. The usual trap is pasting them into a command: they stay in the shell history, and in the process list while the command runs. Prefer imapsync's --passfile1 option, which reads the password from the first line of a file, over --password1, which imapsync's own documentation discourages.
Work in a temporary folder created with umask 077, on a machine you control, never on a colleague's shared workstation. The batch file is deleted at the end with shred -u, and the target passwords are changed afterwards if the client sent them over a channel that is not confidential. A batch file forgotten in a folder synced to a personal cloud is an incident, not a detail.
If a source mailbox requires an app password, ask the client for it explicitly: the usual password will be refused.
The two-pass sync, one mailbox then the batch
Prepare the working folder
umask 077 && mkdir client-batch && cd client-batchthenmkdir logs. Nothing in this folder should end up in a Git repository or a synced folder.Write the batch file
A
mailboxes.csvfile, one line per mailbox:source user;source password;target user;target password. The hosts are set in the command, as in the example in imapsync's documentation. A password containing a semicolon breaks the line: pick another separator for that batch.Dry-run a single mailbox
imapsync --dry --host1 imap.old-provider.com --user1 [email protected] --passfile1 p1 --host2 imap.new-provider.com --user2 [email protected] --passfile2 p2 --ssl1 --ssl2 --automapcopies nothing and shows what would be done.--automapmatches common folders (Sent, Drafts, Junk) whose name differs between servers.Record the folder sizes
Add
--justfoldersizesto the same command: imapsync prints the initial sizes on both sides and stops. Keep that output, it is the baseline for the final count.Run the first pass on that mailbox
Remove
--dryand--justfoldersizes, add--logfile logs/contact.txt. A rerun does not retransfer what is already there, and nothing is deleted on the target by default: do not add--delete2before the end of the project.Run the batch
while IFS=';' read -r u1 p1 u2 p2; do printf '%s' "$p1" > p1; printf '%s' "$p2" > p2; imapsync --host1 imap.old-provider.com --user1 "$u1" --passfile1 p1 --host2 imap.new-provider.com --user2 "$u2" --passfile2 p2 --ssl1 --ssl2 --automap --logfile "logs/$u1.txt"; echo "$u1;$?" >> results.csv; done < mailboxes.csvRead each mailbox's exit code
grep -v ';0$' results.csvlists the mailboxes that are not at zero. The useful codes are 16, 161 and 162 (authentication), 113 (over quota on the target) and 101 or 102 (cannot connect to one of the two hosts).Switch the MX, then replay the same batch
After the MX change, rerun exactly the same loop: that is the delta pass. It only copies messages that arrived since the first pass. Replay it at D+1 and D+3, then
shred -u mailboxes.csv p1 p2.
Verify arrival instead of believing it
A "finished" sync is not proof. What is verified is a count: rerun --justfoldersizes on each mailbox, source side and target side, and compare folder by folder the number of messages and the size. A gap must be explained line by line (trash deliberately excluded, duplicates merged, unsubscribed folder), not rounded away. We do not say "lossless"; we say "matching count on every folder, gaps explained".
Then the end-to-end test: send a message from an external address to each migrated mailbox and check it arrives on the new server; reply from the target's webmail and check it reaches an external recipient. In the received message's headers, check that SPF, DKIM and DMARC are pass. Finally, really open one mailbox per domain in a freshly configured mail client: that is what reveals an unsubscribed folder or a badly transmitted password.
Troubleshooting: the errors that keep coming back in batches
AUTHENTICATIONFAILEDand exit code 161 or 162 — wrong password, app password required, or IMAP disabled for that account. 161 designates the source, 162 the target: check the right half first.- Code 113,
OVERQUOTA— the target mailbox is too small. Raise the quota on the target from the inventory before rerunning, otherwise the delta pass will fail in the same place. - Code 101 or 102 — host unreachable: firewall, wrong port, or the source provider's limit on simultaneous connections. Run the batch one mailbox at a time, not in parallel, and space out the retries.
- Duplicated or badly named folders — the hierarchy separators differ (dot on one side, slash on the other). Rerun the
--dry --justfolderstest and adjust--automapbefore copying. - Messages present twice — identification relies on headers. If a client reports duplicates, read the
--useheader "Message-Id"option in imapsync's documentation before rerunning.
Do not shut the old service on cutover day
Keep the original mailboxes active for at least a week after the MX change and ask the client to check both in the meantime. A sender whose resolver kept the old MX, or whose server retries a deferred delivery, will still drop mail at the old address; the delta pass brings it over, but only if the account still exists. Raise the TTL and cancel the old service only once the last delta pass finds no new message.
Receiving the mailboxes: what web hosting covers, and what it does not
ServOrbit's cPanel web hosting includes professional email: you create the mailboxes in cPanel, set their quota, and the client reaches the webmail; the guide "Create a business email address in cPanel" details the steps. The number of mailboxes depends on the plan chosen, to be read on the plan page when you size the batch.
Be precise about the scope, though. ServOrbit's portfolio migration assistant, described in "Migrate Your Entire Portfolio to ServOrbit in a Single Order", covers domains and cPanel hosting accounts. It does not move the IMAP mailboxes of a third-party provider. Assisted migration exists as an option: ask for it and confirm it before promising a date to the client, never assume it is included.
Once the mailboxes have arrived, device setup follows the guide "Set up your business email on a phone or Outlook".
What you hand over to the client at the end
A migration ends with a document, not with "it's done". Hand the client the annotated inventory table (mailbox, status, explained count gaps), the list of recreated aliases, forwards and autoresponders, the list of reconfigured devices, and the date on which the old service will be cancelled. Attach the before and after count outputs: if a complaint comes three weeks later, they let you answer with figures.
Also note what was not covered: contacts, calendars, sorting rules not recreated. A routine that returns "OK" only says what it looks at. And schedule a check ten days later: a rarely used mailbox will only report its problem then.