Published 2026-04-07
Migrating from AWS WorkMail to Microsoft 365
Published 2026-04-07
In January 2026, Amazon announced that AWS WorkMail would be discontinued. Organizations that depended on WorkMail for email now face a migration to another provider, often without a clear path forward.
Microsoft 365 is a common destination. It offers comparable mail, calendar, and directory features, broad client support, and a mature administrative ecosystem. But the migration itself is far from turnkey: there is no built-in wizard, no one-click export, and surprisingly little practical guidance available from either vendor.
This guide documents what's actually involved, based on first-hand experience migrating a multi-domain organization from WorkMail to MS365.
What a Complete Migration Looks Like
Migrating email between providers is more than copying messages from one server to another. A complete migration touches six distinct areas:
- Message content — every email in every folder, for every user
- Folder structure — Inbox, Sent Items, and any custom folders the user has created
- Email aliases — alternate addresses that deliver to the same mailbox
- Distribution groups — mailing lists that deliver to multiple users
- DNS records — MX, SPF, DKIM, DMARC, and autodiscover
- Client configuration — Outlook, mobile devices, and applications that send mail
Getting the messages across is the most time-consuming step, but it's the others that tend to cause problems when overlooked. A forgotten alias means bounced mail. A missing SPF record means your messages land in spam. A group that doesn't get recreated means a team silently stops receiving updates.
Phase 1: Preparation
Set up your MS365 environment
Before migrating any mail, you need a working MS365 tenant with mailboxes ready to receive messages:
- Add your domain(s) to MS365 via the Admin Center. Microsoft will ask you to add a TXT record to your DNS for verification. This does not affect mail delivery.
- Create mailboxes for each user being migrated. These can be licensed user mailboxes or shared mailboxes (shared mailboxes do not require a license).
- Do not change your MX records yet. Keep mail flowing to WorkMail until the migration is verified. DNS cutover happens last.
Take inventory
Document everything that needs to move. This includes users and their primary addresses, any email aliases (alternate addresses that deliver to the same person), distribution groups and their members, and approximate mailbox sizes. Large mailboxes with more than 100,000 messages take significant time to migrate at IMAP speeds.
You can enumerate users, aliases, and groups using the AWS CLI. Write this information down — you'll need it for the manual steps that no automated tool can handle.
Phase 2: Message Migration
Option A: Microsoft's built-in IMAP migration
Microsoft offers a built-in IMAP migration feature in Exchange Online. You provide a CSV file mapping WorkMail users to MS365 mailboxes, and Exchange pulls messages directly from WorkMail's IMAP server.
This works, but has notable limitations:
- Folder structure may not be preserved. Messages can land in the Inbox regardless of their original folder.
- Transient errors can be fatal. If the IMAP connection drops under sustained load, the migration for that user may fail and need to be restarted.
- No checkpointing. A failed migration for a large mailbox means starting from the beginning.
- Limited visibility. Progress reporting is minimal, and diagnosing failures requires working through Exchange migration logs.
For small mailboxes, this approach works fine. For larger mailboxes or organizations with many users, consider a more resilient alternative.
Option B: aw2ms365
We built aw2ms365, an open-source command-line tool that reads messages from WorkMail via IMAP and writes them to MS365 via Exchange Web Services (EWS). It was designed to address the limitations above:
- Preserves folder structure. Messages are placed in the correct folder on MS365.
- Checkpointed and resumable. Progress is saved every 10 messages. If the process is interrupted, it picks up exactly where it left off.
- Automatic retry with backoff. Transient failures are retried automatically with exponential backoff.
- Built-in verification. After migration, you can compare message counts between source and destination.
The tool requires Node.js and an MS365 app registration with EWS permissions. It runs on macOS, Linux, and Windows. Full setup instructions and documentation are available in the project repository.
Phase 3: Post-Migration Manual Steps
Recreate aliases
Email aliases do not transfer between providers. Every alternate address that delivers to a user's mailbox on WorkMail needs to be explicitly recreated on MS365.
This is done through Exchange Online PowerShell. If you have many aliases, script the process using the inventory you collected earlier. A forgotten alias means bounced mail — and the bounce goes to the sender, not to you, so you may not notice for days.
Recreate distribution groups
WorkMail groups are completely separate from MS365 groups. Group addresses, member lists, and delivery rules all need to be recreated manually in Exchange Online.
This is easy to overlook. Distribution groups often serve automated systems — monitoring alerts, ticketing systems, notification services — where a silent delivery failure may not be noticed until something goes wrong.
Update DNS records
Once you've verified that messages, aliases, and groups are all in place, update your DNS records to route incoming mail to MS365:
- MX — point to your domain's MS365 mail protection endpoint
- SPF — include Microsoft's SPF servers
- DKIM — add the CNAME records provided by Exchange Admin and enable signing
- DMARC — set your policy (start with monitoring mode while you verify)
- Autodiscover — CNAME for automatic client configuration
Do not change MX records until you are confident the migration is complete. Once MX points to MS365, new mail goes there. If aliases or groups are missing, some of that mail will bounce.
Reconfigure applications
Any system that sends email through WorkMail — web applications, monitoring tools, CRM platforms, network printers — needs to be reconfigured to send through MS365 or an alternative relay.
Things We Learned the Hard Way
These come from first-hand experience. Some of them cost hours. None of them were documented anywhere we could find.
Before you start
- Inventory aliases and groups before you start, not after. We didn't discover our missing distribution groups until a test email bounced — days after we thought the migration was complete. Aliases and groups are separate entities from mailboxes, and nothing in the migration process will remind you they exist.
- Back up everything to S3 first. WorkMail's
StartMailboxExportJobAPI can export each mailbox as a zip of .eml files. It's slow for large mailboxes, but it gives you an independent backup outside both mail systems. Do this before you begin, not after something goes wrong. - Large mailboxes take a long time. At IMAP speeds, a 200,000-message mailbox takes roughly 55 hours. A 150,000-message mailbox took multiple days with repeated restarts due to connection failures. Set expectations with users accordingly.
IMAP and connectivity
- WorkMail IMAP drops connections under sustained load. Microsoft's own built-in IMAP migration hit 60 transient connection failures and quit permanently — on a 150,000-message mailbox at 72% completion. We had to restart the migration repeatedly, each run getting a few thousand more messages through before the next failure. Any migration approach that doesn't handle automatic reconnection will fail on large mailboxes.
- Password resets take a moment. If you reset a WorkMail password via the AWS CLI, the IMAP server may reject the new password for 30–60 seconds. Wait and retry before assuming you typed it wrong.
Microsoft 365 and Entra ID
- Microsoft's admin portals are a maze. App registrations are in Entra ID. Mailbox management is in Exchange Admin Center. Migration batches require PowerShell. Domain verification is in MS365 Admin Center. DKIM sometimes requires PowerShell too. None of these consoles link to each other reliably, and they sometimes show different views of the same data. Budget time just for finding where things are.
- Client secrets are shown once and only once. When you create a client secret in Entra ID, the value is displayed at the moment of creation. If you navigate away without copying it, you have to delete it and create a new one. There is no way to retrieve a secret after the fact.
- Don't confuse the secret ID with the secret value. The secrets table in Entra ID shows two columns that look deceptively similar: "Secret ID" (a UUID that identifies the secret) and "Value" (the actual secret string you need). The error message when you use the wrong one says "Invalid client secret" with no further clarification.
- YAML eats special characters. MS365 client secrets frequently contain
~, which YAML interprets as a null value prefix. Passwords may contain!or#. Always wrap credential values in single quotes in configuration files. This caused silent authentication failures that were difficult to diagnose because the config looked correct at a glance. - Exchange Online PowerShell is broken on macOS 15. The browser-based MSAL
authentication fails with a platform exception. The workaround is device code authentication:
Connect-ExchangeOnline -Device. This was not documented by Microsoft at the time of writing. - MS365 anti-spam may quarantine migrated messages. Importing old messages can trigger phishing or spam filters, especially messages from external senders with outdated SPF records. You may need to create Exchange transport rules to trust your own domains during migration.
Message fidelity
- EWS-imported messages may have empty search fields. Messages imported via Exchange Web Services with raw MIME content are stored correctly, but Exchange doesn't always populate its searchable properties (To, CC, sometimes Subject) from the MIME headers. Messages display correctly when opened in Outlook — the data is all there — but server-side searches by recipient may not find them.
- Message-IDs change across mail systems. We initially tried to detect duplicate messages by comparing Message-ID headers between source and destination. This doesn't work: WorkMail assigns its own Message-ID, and Exchange assigns yet another when importing. The original sender's Message-ID may not survive the round trip. Subject line and sent date proved to be a more reliable fingerprint.
- Character encoding creates invisible mismatches. Email subjects can be encoded in various character sets (windows-1252, ISO-8859-1, UTF-8) using MIME encoded-word syntax. A subject containing a smart quote in the source looks completely different as a raw string than the decoded version Exchange stores. Any logic that compares source and destination messages needs to account for this.
After migration
- Old messages flood the Inbox. The IMAP migration dumps all messages into the Inbox regardless of age. Ten years of email suddenly appears alongside today's mail. Plan to do a bulk archive sweep (by date) immediately after migration completes, or users will be overwhelmed.
- Outlook may not show newly populated folders. After moving 100,000+ messages into an Archive folder server-side, Outlook may show the folder as empty for a while. The messages are there — Outlook just hasn't synced the folder contents yet. Click on the folder and wait.
- Source mailboxes may be full of spam. In our migration, over half the messages in
one user's mailbox were spam. If you're importing from .eml files, consider filtering by spam
headers (
X-Spam-Status: Yes) and Junk folder paths before importing. It's much easier to filter before import than to clean up afterward. - User Principal Name vs. primary email address. In MS365, the User Principal Name
(UPN) determines the login address and the default send-from address in Outlook. The "primary SMTP
address" is a separate setting that controls which address appears in the directory. If your users
need to sign in and send mail as
user@yourdomain.comrather than the UPN they were provisioned with, you need to change the UPN — not just the primary SMTP address. This is done in the MS365 Admin Center under the user's account settings, and it only works if the domain is verified for login in your tenant. Change one identity field at a time; MS365 does not handle multiple simultaneous changes gracefully.
Operations
- Test with one small mailbox first. We migrated a 17-message test mailbox before attempting the 200,000-message production ones. That test uncovered configuration issues, authentication problems, and a deduplication gap — all fixable in minutes rather than hours.
- Checkpoints are local to each machine. If you start a migration on one computer and continue from another, the second machine has no record of what was already migrated. Built-in deduplication can prevent duplicate messages, but it's slower than checkpoint-based resumption.
- Export your WorkMail data to S3 before you start. WorkMail's
StartMailboxExportJobAPI exports each mailbox as a zip of .eml files to S3. It's slow for large mailboxes, but it's the only way to get an independent backup that doesn't depend on either mail system running. We didn't do this until partway through our migration, and wished we'd done it first. - Don't decommission WorkMail until you're certain. WorkMail is your only backup until migration is fully confirmed. Verify message counts, test mail flow on every alias, confirm every distribution group, and monitor for at least a week before decommissioning. The temptation to clean up quickly is strong. Resist it.
Realistic Timeline
For a small organization (5–10 users, moderate mailbox sizes):
| Phase | Duration | Notes |
|---|---|---|
| MS365 setup and domain verification | 1–2 days | Includes DNS propagation |
| Message migration | 1–7 days | Depends on mailbox sizes |
| Alias and group recreation | 1–2 hours | Script it if you have many |
| Verification | 1 day | Spot-check messages, test mail flow |
| DNS cutover | 1 day | MX, SPF, DKIM, DMARC, autodiscover |
| Monitoring | 1–2 weeks | Watch for bounces, spam, missed aliases |
| WorkMail decommission | After monitoring | Don't rush this |
For larger organizations or mailboxes exceeding 100,000 messages, extend the migration phase and consider running migrations for different users in parallel.