Skip to content

Migration

Christopher Holloway edited this page Sep 24, 2026 · 11 revisions

Migration

Written on 24 September 2026 from the repository at master 540347500: hmailserver/docs/Migration.md. 6.3.3, published 15 September 2026, is the latest release. The routes from another IMAP server (a mirroring external account), from mbox files, from a Maildir, from Outlook and from the upstream hMailServer are in 6.3.3; the webmail's own Other accounts with Gmail and Outlook.com sign-in, and the migration jobs (schema 6090), are in the tree after 6.3.3 and not yet released.

How to bring existing mailboxes into this server. Moving an installation of hMailServer is elsewhere: Upgrading hMailServer for a release-to-release upgrade and the move from the original project, Migrating the Database Backend for a change of database, and Relocating an Installation for a new machine or disk.

Which route

You are moving Use Keeps Does not keep
One person's own mailbox, by that person The webmail's Other accounts (tree after 6.3.3) Folders brought over as copies, then new mail collected Rules, signatures
A few mailboxes that must stay in step until the cut-over An external account with the mirror on - the server collects every folder over IMAP until it is switched off Folders, every message byte for byte, the five standard flags, the internal date Subscriptions, custom keywords, ACLs
Many mailboxes - hundreds - from an IMAP server, Google Workspace or Microsoft 365, with contacts, calendars and a report per mailbox A migration: a job per mailbox (tree after 6.3.3) Folders into their special-use counterparts, every message byte for byte, flags and keywords, the date; contacts and calendars Rules, signatures, shared mailboxes, ACLs, Gmail's labels as labels
mbox files (Thunderbird's profile, Apple Mail, a Unix spool) The Import Tool, one folder per file Every message, the date from the headers Flags - mbox has no standard for them
A Maildir (Dovecot, Courier) The Import Tool's Select Maildir The Maildir++ hierarchy, every message, the flags in the file names Custom keywords
Outlook PST files Outlook itself, over IMAP: add this server as an IMAP account and drag the folders across Whatever Outlook uploads: folders, messages, read and flagged state Anything Outlook does not put on the wire. The server does not read PST, deliberately
The accounts themselves The Import Tool's text-file import, or a spreadsheet over REST and hmctl (tree after 6.3.3), or SCIM from the identity provider (tree after 6.3.3) - first, since every route above needs the account to exist Addresses, passwords, quotas Mail

The external account and its mirror are on the account dialog's External tab in the Control Panel, and on the Deck's fetch-accounts view; Mirror every folder (MirrorFolders) is what turns a collection of the INBOX into a copy of every folder. A new external account for the mirror is the safe choice: one that has been collecting the INBOX alone collects it once more when the mirror is switched on.

The person moving their own mailbox

In the tree after 6.3.3, not yet released. Settings, Other accounts in the webmail. The person picks their old provider - Gmail, Outlook.com, Yahoo Mail and iCloud Mail fill in the server, port and encryption and say what each asks for - gives the user name and password, chooses whether to leave the mail there, and ticks Bring the folders over too. It is an external account like any other, with the filters on, the host held to public addresses unless the administrator turns on reader_fetch_accounts_private_addresses, an interval of at least fifteen minutes, and at most reader_fetch_accounts_max of them (3 by default).

Signing in rather than giving a password. Outlook.com no longer accepts a password from another mail server, and Gmail takes only an app password. Where an administrator has registered this server with Google and Microsoft, the page offers Sign in to Gmail and Sign in to Outlook.com: the person signs in there and grants IMAP access, and the external account logs in with XOAUTH2 - no password is stored, and the permission can be taken back at the provider. The first collection then lists the folders to tick, with Gmail's All Mail, Starred and Important unticked so that nothing arrives twice. The registration is import_oauth_redirect_base_url (the redirect URI is that plus /portal/oauth/callback) and each provider's client id and secret, on PUT /api/v1/settings.

Five hundred mailboxes: migration jobs

Schema 6090, in the tree after 6.3.3, not yet released. Moving an organisation needs something the server runs itself: a job per mailbox with a state, no more load on the source than it will bear, a job that goes on from where it was after a failure or a restart, a report per mailbox, and the contacts and calendars beside the mail. It is administered over REST under /api/v1/migrations and in the Control Deck's Migrations view; there is no COM interface and no Control Panel page.

  1. Create the accounts first - with a spreadsheet import, the Import Tool or SCIM.

  2. Create the migration, naming its source: imap (any IMAP server, a password per mailbox), google or microsoft365 (each mailbox signed in to by its owner). A migration runs concurrency jobs at once (4 by default, up to 32) at messages_per_minute each.

  3. Add the jobs - a CSV of sourceuser,secret,target, up to 5,000 lines, every line checked before any job is made and the first bad line named:

    sourceuser,secret,target
    anna@old.example,Anna's old password,anna@example.com
    carla@example.com,,carla@example.com
    

    For Google and Microsoft 365 the secret is left empty: the answer carries a one-use sign-in link per job for its owner to open, sign in as that mailbox and grant access. A sign-in as anybody else attaches nothing.

  4. Start it, and watch each job's state, phase (mail, contacts, calendars, report), progress and last error in the Deck, or download summary.csv for the spreadsheet.

What a job does. It lists the source's folders and maps each to one here: the INBOX to the INBOX, a special-use folder (Sent, Drafts, Junk, Trash, Archive) to the account's own folder of that use whatever it is called, everything else by name. Every message is copied byte for byte with its flags, keywords and date. Then the contacts and calendars: from an IMAP server by CardDAV and CalDAV found by RFC 6764 discovery (or dav_url); from Google by its CardDAV and CalDAV; from Microsoft 365 by Microsoft Graph. A phase that cannot run is skipped with its reason and never fails a job whose mail is copied.

It survives being interrupted. After every fifty messages and at the end of each folder the job writes its resume marks; whatever stops it - a network failure, a pause, the service restarting - it goes on from those marks, and it checks what it wrote since it started so that each message arrives once, however often it is interrupted. A failure time may mend is retried after 1, 5 and 15 minutes and then hourly; wrong credentials fail the job at once, and Retry takes a mended password.

It is throttled three ways: concurrency per migration, MigrationConnectionsPerHost (4 by default) across every migration from one source host - a provider counts sessions per client address

  • and at most 64 jobs on the server at once.

The report per job says, folder by folder, how many messages the source held, how many were copied and why any were skipped (duplicate, another_folder, too_large, refused, gone, empty), then the contacts and calendars, the bytes, the duration and the errors met.

Who may. Reading needs view_accounts and writing manage_accounts in the target's domain; the server administrator creates a migration, and a domain administrator then sees and adds to it. The audit trail records migrations and jobs; a job's own progress is not recorded. Jobs are not carried by a backup: a restore is not a moment in a migration.

What is not migrated

  • Rules and filters (Gmail's filters, Outlook's inbox rules, Sieve), signatures, out-of-office replies and forwarding - make them again here.
  • Shared mailboxes and permissions: other users' and shared mailboxes are left with a note, and a Microsoft 365 shared mailbox, which nobody signs in as, cannot be a job.
  • Subscriptions: every folder is created subscribed.
  • Gmail's labels as labels. Over IMAP a label is a folder; a google migration copies each message once, into the first folder it meets it in, and All Mail brings only what no label held. The star arrives as \Flagged.
  • Contact groups, and contacts with no address.
  • From Microsoft 365, the default contacts folder and the default calendar only.
  • PST files, which the server does not read - Outlook is the reliable reader of what Outlook wrote.

The full document, with every field, route and refusal, is Migration.md.

See also: The Webmail · The Control Deck · Sign-in and Identity · Connecting a Mail Client · Upgrading hMailServer

Home — full index

Start here

1. Install and run

2. Secure it

3. Operate it

4. Extend it

5. Contribute to it

Look it up — from any journey


About this wiki

Clone this wiki locally