Migrating IMAP Accounts Between Remote Hosts

I have come to rely on IMAP for email access. It is the most convenient way to ensure access to all my mail from more than one computer. I recently switched to a new hosting provider and I didn’t want to lose all of my archived email stored on the old host’s server. Fortunately, I found a Perl script designed to synchronize IMAP mailboxes between two servers. The script is called **imapsync**.

I was able to install imapsync from the Ubuntu repositories. The package includes a man page which explains the options and contains some example use cases. My needs were simple–copy everything from point A to point B.

The first step is to create mailboxes for the users in question on the new server. I did this, preserving the same passwords as well as the same usernames. It is not necessary to use the same login/password on each server, but doing so allowed me to simplify the bash command line a great deal. Below are the commands I used to migrate two mailboxes, followed by an explanation of each command:

$ touch passwd_nick passwd_karie
$ chmod 600 passwd_*
$ echo “[HISPASSWORD]” > passwd_nick
$ echo “[HERPASSWORD]” > passwd_karie
$ for USER in nick karie; do
> imapsync \
> –host1 [SOURCE_IP] –user1 $USER –passfile1 passwd_$USER \
> –host2 [DEST_IP] –user2 $USER –passfile2 passwd_$USER \
> –ssl1 –ssl2 –noauthmd5
> done

The **touch** and **chmod** commands create empty files with the appropriate permissions to prevent other local users from viewing the contents. This may not be necessary on every machine, but it is a good practice to consider privacy when working with plaintext passwords. It is possible to pass plaintext passwords to imapsync using the arguments `–password1` and `–password2`, but they would then appear to any local user who executes `ps axww` for as long as the command runs.

The **echo** lines actually write the passwords to the empty files. Obviously, I used placeholder text within the brackets.

The **for** statement iterates through the usernames *nick* and *karie*, and the bash interpreter reads these values wherever `$USER` is seen in the imapsync argument list. `[SOURCE_IP]` and `[DEST_IP]` are placeholders for the numeric IP addresses of each remote server.

The `–ssl1` and `–ssl2` flags enable SSL for their respective connections. This is almost certainly preferred for better security. If your servers support TLS you can use `–tls1` and `–tls2` instead. I also had to pass the `–noauthmd5` flag, as neither server in my situation supported that feature.

The script ran for a long time. In fact, I left it running and went to work. When I got home I ran it again to transfer whatever new messages had been delivered since the sync (there were 25). Then, confident that things were ready to go, I logged in to my domain registrar and updated the nameservers to reflect the new host. Last but not least, I opened up Thunderbird to see if it worked. Thunderbird didn’t even notice the switch. In fact, it worked so flawlessly that I actually had to perform a DNS search to make sure the nameservers had been updated properly.

As the name suggests, imapsync is designed to synchronize IMAP mailboxes. Migration is only a small part of its featureset. It may be wise to consider implementing this script into your normal backup routine; of course, this requires that a backup IMAP server be running.

While a number of utilities exist that can migrate mailboxes, the simplicity of imapsync makes it a great choice for occasional use.


  • Gilles Lamiral says:


    Thanks for this good article about imapsync!

    PS: we can’t see who wrote this article, no signature, no name.

  • Nick Bair says:


    Thank you for creating such a useful script! You saved me a ton of hard work during the migration. I’m glad you’re happy with my writeup on such a great tool.

    BTW, my name is Nick Bair. I authored this post as well as all others on this blog.

Leave a Reply

Your email address will not be published. Required fields are marked *