imapsync is a Perl CLI tool for migrating and synchronising email between IMAP servers. It preserves folders, flags, dates, and headers with minimal disruption.
Installation
# Debian / Ubuntu (from distro repo)
sudo apt install imapsync
# From source (latest version)
git clone https://github.com/imapsync/imapsync.git
cd imapsync
perl -MCPAN -e "install Mail::IMAPClient IO::Socket::SSL Digest::MD5"
sudo cp imapsync /usr/local/bin/
# Verify
imapsync --version
Basic Sync
# Migrate a single mailbox
imapsync \
--host1 imap.source.com --user1 [email protected] --password1 'secret1' \
--host2 imap.target.com --user2 [email protected] --password2 'secret2'
Common Options
| Option | Purpose |
|---|
--ssl1 / --ssl2 | Enable TLS on connection (omit for plain IMAP on port 143) |
--port1 / --port2 | Custom port (993 for IMAPS, 143 for IMAP, 587 for submission) |
--dry | Dry-run — show what would be synced without making changes |
--delete1 | Delete messages on server1 after successful copy (migration mode) |
--delete2 | Delete messages on server2 not in server1 (two-way purge) |
--delete2folders | Remove folders on target not present on source (mirror mode) |
--justfolders | Sync folder structure only, skip messages |
--justconnect | Test connectivity only — validates credentials and exits |
--useuid | Use UID for message matching (safer for dedup, default: on) |
--skipcrossduplicates | Skip duplicate messages that exist in multiple source folders |
SSL / TLS
# IMAPS (port 993) — explicit SSL
imapsync --ssl1 --ssl2 \
--host1 imap.source.com --user1 [email protected] --password1 'p1' \
--host2 imap.target.com --user2 [email protected] --password2 'p2'
# STARTTLS (port 143 with upgrade)
imapsync --notls1 --tls2 \
--host1 mail.old.com --user1 [email protected] --password1 'p1' \
--host2 mail.new.com --user2 [email protected] --password2 'p2'
Selective Sync
# Sync only a specific folder
imapsync \
--host1 imap.source.com --user1 [email protected] --password1 'p1' \
--host2 imap.target.com --user2 [email protected] --password2 'p2' \
--folder INBOX
# Exclude a folder
imapsync ... --exclude '^Spam|^Trash|^Junk'
# Include only folders matching a pattern
imapsync ... --include '^INBOX|^Sent|^Archive'
# Sync only messages from the last 7 days
imapsync ... --maxage 7
Handling Large Mailboxes
# Split sync — messages per folder call (reduce memory)
imapsync ... --split1 100 --split2 100
# Limit messages per sync batch
imapsync ... --maxmessages 5000
# Resume interrupted sync (skip already-copied messages)
imapsync ... --resynccopy --useuid
# Increase timeout for slow connections (default 120s)
imapsync ... --timeout1 300 --timeout2 300
Migrate Multiple Users (Batch)
# users.txt format: user1;password1;user2;password2
while IFS=';' read -r u1 p1 u2 p2; do
imapsync \
--host1 imap.old.com --user1 "$u1" --password1 "$p1" \
--host2 imap.new.com --user2 "$u2" --password2 "$p2" \
--ssl1 --ssl2 --delete1
echo "Done: $u1 -> $u2"
done < users.txt
Debugging
# Verbose output
imapsync ... --debug --debugimap
# Log to file
imapsync ... --logfile /tmp/imapsync.log
# Show only errors and summary
imapsync ... --quiet --errorsonly
# Test connection before full sync
imapsync --host1 imap.source.com --user1 [email protected] --password1 'p1' --justconnect
Exit Codes
| Code | Meaning |
|---|
| 0 | Success — all messages synced |
| 1 | Partial failure — some messages skipped |
| 2 | Authentication or connection error |
| 3 | Fatal error — folder creation failed |
| 4 | Internal imapsync error |
Pitfalls
- App passwords: Many providers (Microsoft 365, Google Workspace) require an app-specific password, not the account password. Enable IMAP access in the admin panel first.
- Rate limiting: Some providers (Gmail, O365) throttle connections. Add
--sleep 1 between messages or batch small folders.
- Folder encoding: Non-ASCII folder names may fail. Use
--regextrans2 's/./ /' as a last resort — better to check the actual folder list with --justfolders --dry.
- No attachment corruption: imapsync copies raw message bytes — attachments are preserved as-is. If attachments appear corrupted, check for server-side size limits (e.g., attachmentStripping in Dovecot).
- Date preservation: By default imapsync preserves
Received and Date headers. Add --syncinternaldates to force target folder dates to match source.