Imapsync Cheatsheet
imapsync is a powerful Perl CLI tool designed for incremental IMAP-to-IMAP mailbox migrations and synchronization. It preserves message flags, headers, internal dates, and folder structures while skipping identical messages during repeated runs.
Installation
# Debian / Ubuntu
sudo apt update && sudo apt install imapsync
# RHEL / CentOS / AlmaLinux / Rocky Linux (EPEL repository)
sudo dnf install epel-release -y
sudo dnf install imapsync -y
# Arch Linux
sudo pacman -S imapsync
# macOS (via Homebrew)
brew install imapsync
# Docker container (official image)
docker run -it gilleslamiral/imapsync imapsync --version
# Build from source (latest release)
git clone https://github.com/imapsync/imapsync.git
cd imapsync
sudo make installVerify installation:
imapsync --versionBasic Migration Commands
Standard IMAP to IMAP Migration
imapsync \
--host1 imap.source-server.com --port1 993 --ssl1 \
--user1 [email protected] --password1 'SourcePassword123!' \
--host2 imap.target-server.com --port2 993 --ssl2 \
--user2 [email protected] --password2 'TargetPassword123!'Test Connection & Credentials (Dry Run)
# Validate login credentials without transferring emails
imapsync \
--host1 imap.source.com --user1 [email protected] --password1 'pass1' \
--host2 imap.target.com --user2 [email protected] --password2 'pass2' \
--justconnect
# Dry run — simulate synchronization without copying or deleting
imapsync \
--host1 imap.source.com --user1 [email protected] --password1 'pass1' \
--host2 imap.target.com --user2 [email protected] --password2 'pass2' \
--dryEssential Flags & Options
| Flag / Option | Description |
|---|---|
--ssl1 / --ssl2 | Use SSL/TLS connection (typically port 993). |
--tls1 / --tls2 | Use STARTTLS connection (typically port 143). |
--notls1 / --notls2 | Force plain unencrypted connection. |
--dry | Perform a dry run without copying or deleting messages. |
--justconnect | Connect and authenticate only, then exit. |
--justfolders | Synchronize folder structures without transferring messages. |
--delete1 | Delete messages on source server (host1) after copying to target. |
--delete2 | Mirror mode: Delete messages on target (host2) if not on source. |
--delete2folders | Remove folders on target (host2) that do not exist on source. |
--useuid | Use IMAP UID matching for duplicate prevention (default: enabled). |
--skipcrossduplicates | Avoid copying duplicate emails that exist across multiple source folders. |
--useheader "Message-Id" | Match emails using specific headers to prevent duplicates. |
--subscribefolders | Automatically subscribe target account to all created folders. |
Folder Selection & Filtering
Folder Inclusion & Exclusion
# Sync specific folder only
imapsync ... --folder INBOX
# Sync multiple specific folders
imapsync ... --folder INBOX --folder "Sent Items" --folder "Archive"
# Include folders matching a regular expression
imapsync ... --include '^INBOX|^Sent|^Projects'
# Exclude spam, trash, or junk folders
imapsync ... --exclude '^Spam|^Trash|^Junk|^Drafts'Date & Size Filtering
# Sync messages newer than N days (e.g. last 30 days)
imapsync ... --maxage 30
# Sync messages older than N days
imapsync ... --minage 30
# Skip emails larger than N bytes (e.g. 50 MB)
imapsync ... --maxsize 52428800
# Skip emails smaller than N bytes (e.g. 1 KB)
imapsync ... --minsize 1024Folder Mapping & Renaming
imapsync supports regular expression replacements to map folder names between different IMAP server formats (e.g. INBOX.Sent -> Sent).
# Map INBOX subfolders (cPanel style) to standard root folders (Dovecot/Exchange style)
imapsync ... --regextrans2 's/^INBOX\.//'
# Rename "Sent Items" to "Sent"
imapsync ... --regextrans2 's/^Sent Items$/Sent/'
# Rename "Trash" to "Deleted Items"
imapsync ... --regextrans2 's/^Trash$/Deleted Items/'
# Multiple folder transformations
imapsync ... \
--regextrans2 's/^INBOX\.//' \
--regextrans2 's/^Sent Messages$/Sent/' \
--regextrans2 's/^Junk E-mail$/Spam/'Mail Provider Examples
Gmail / Google Workspace (Source)
Gmail requires App Passwords if 2FA is enabled, or IMAP enabled in account settings.
imapsync \
--host1 imap.gmail.com --port1 993 --ssl1 \
--user1 "[email protected]" --password1 "abcd-efgh-ijkl-mnop" \
--host2 imap.target.com --port2 993 --ssl2 \
--user2 "[email protected]" --password2 "TargetPass123" \
--exclude '^\[Gmail\]/Trash|^\[Gmail\]/Spam'Microsoft 365 / Outlook (Target)
imapsync \
--host1 imap.oldserver.com --port1 993 --ssl1 \
--user1 "[email protected]" --password1 "OldPassword" \
--host2 outlook.office365.com --port2 993 --ssl2 \
--user2 "[email protected]" --password2 "M365AppPassword" \
--subscribefolderscPanel to DirectAdmin / Dovecot Migration
imapsync \
--host1 mail.cpanel-server.com --port1 993 --ssl1 \
--user1 "[email protected]" --password1 "CpanelPassword" \
--host2 mail.directadmin-server.com --port2 993 --ssl2 \
--user2 "[email protected]" --password2 "DAPassword" \
--regextrans2 's/^INBOX\.//' \
--subscribefoldersPerformance & Reliability Tuning
Large Mailbox & Slow Connection Settings
imapsync \
--host1 imap.source.com --user1 u1 --password1 p1 \
--host2 imap.target.com --user2 u2 --password2 p2 \
--split1 100 --split2 100 \
--maxmessages 1000 \
--timeout1 300 --timeout2 300 \
--resynccopy \
--useuidRate Limiting & Sleep (Prevent Server Throttling)
# Add 1-second delay between message copies (prevents Gmail/O365 rate limits)
imapsync ... --sleep 1
# Limit bandwidth transfer speed (bytes per second, e.g. 2 MB/s)
imapsync ... --maxbytespersecond 2097152Batch Migration Script (Multiple Accounts)
Create a CSV/text file accounts.csv with format source_user;source_pass;target_user;target_pass:
[email protected];Pass1!;[email protected];NewPass1!
[email protected];Pass2!;[email protected];NewPass2!
[email protected];Pass3!;[email protected];NewPass3!Create a Bash script migrate.sh:
#!/usr/bin/env bash
CSV_FILE="accounts.csv"
LOG_DIR="/var/log/imapsync"
mkdir -p "$LOG_DIR"
SRC_HOST="imap.oldserver.com"
TGT_HOST="imap.newserver.com"
while IFS=';' read -r u1 p1 u2 p2; do
# Skip comments and empty lines
[[ "$u1" =~ ^#.*$ || -z "$u1" ]] && continue
echo "=================================================="
echo "Migrating: $u1 -> $u2"
echo "=================================================="
imapsync \
--host1 "$SRC_HOST" --port1 993 --ssl1 --user1 "$u1" --password1 "$p1" \
--host2 "$TGT_HOST" --port2 993 --ssl2 --user2 "$u2" --password2 "$p2" \
--subscribefolders \
--logfile "$LOG_DIR/${u1}_sync.log"
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "SUCCESS: $u1 migrated completely."
else
echo "WARNING: $u1 completed with exit code $EXIT_CODE. Check log: $LOG_DIR/${u1}_sync.log"
fi
done < "$CSV_FILE"Debugging & Logging
# Log detailed output to a file
imapsync ... --logfile /var/log/imapsync_debug.log
# Enable full IMAP protocol transcript debugging
imapsync ... --debug --debugimap
# Quiet mode — print only summary and errors
imapsync ... --quiet --errorsonlyExit Codes Reference
| Exit Code | Status | Meaning |
|---|---|---|
0 | Success | All messages and folders synchronized cleanly. |
1 | Warning | Sync completed, but some individual messages failed to copy or were skipped. |
2 | Auth Error | Authentication or connection error on host1 or host2. |
3 | Folder Failure | Fatal error creating or listing folders. |
4 | Internal Error | Internal script or memory allocation error. |
Common Troubleshooting Tips
-
Authentication Failed (
AUTHENTICATE failed)- Ensure IMAP access is enabled in the account settings.
- For Gmail and Microsoft 365, generate an App Password instead of using the primary password.
- Verify if two-factor authentication (2FA) is blocking basic login.
-
SSL / TLS Handshake Errors
- Use
--ssl1 --ssl2for port993. - Use
--tls1 --tls2(or--notls1 --tls2) for port143with STARTTLS. - Use
--noauthmd5if the server rejects CRAM-MD5 / DIGEST-MD5 authentication.
- Use
-
Folder Mapping Issues (Nested Folders under INBOX)
- Servers running cPanel or Courier often prefix subfolders with
INBOX.. Use--regextrans2 's/^INBOX\.//'when migrating to Dovecot/Exchange.
- Servers running cPanel or Courier often prefix subfolders with
-
Rate Limit / Quota Exceeded
- Use
--sleep 1or--sleep 2to throttle requests. - Use
--split1 50 --split2 50to process messages in smaller batches and avoid memory exhaustion.
- Use