Home / Alt manpages / doveadm-move(1)

  • doveadm-move(1)
  • User command
  • linux

Move and Copy Mail Safely with doveadm

doveadm move trusts your search query completely, so one stray date range can empty a mailbox instead of tidying it. This guide covers moving and copying messages for one user, a fixed list of users, or a whole domain, checking the exit status and both mailboxes at every stage. The examples use Dovecot 2.3.21+dfsg1-2ubuntu6.5 from the installed dovecot-core package; allow about fifteen minutes, plus time to confirm the query against the right account.

  • A destination mailbox that already exists. Neither command creates one for you.
  • A user or list of users you can name exactly. Wildcards and all-user scans are covered, but only as a deliberate choice.
  • Shell access with the privileges your Dovecot deployment requires. Some installations need an administrative shell, some do not.

Warning

A move removes each matching message from its source mailbox once it lands in the destination, and there is no general command that reliably puts it back after later mail activity. Copy is the safer choice whenever the source has to remain untouched.

1. Confirm the installed command and destination

Check the binary and package before trusting examples written against a different Dovecot release:

$ command -v doveadm
/usr/bin/doveadm
$ dpkg-query -W -f='${Package} ${Version}\n' dovecot-core
dovecot-core 1:2.3.21+dfsg1-2ubuntu6.5

Then check the account's mailbox list without changing anything:

$ doveadm mailbox list -u [email protected]
INBOX
Archive/2026
  • Replace the placeholders. Use a real value for [email protected] and for Archive/2026.
  • Do not expect the destination to appear by itself. Mailbox names are not inferred from the argument you pass to move or copy, and a missing destination makes the command fail.
  • Create a mailbox separately if you need one. Check your site's mailbox policy first rather than improvising a name.

Checkpoint

Write down the exact source mailbox, destination mailbox, account, and date filter before you go any further.

Run doveadm search with the same user and query you intend to change. It lists matching mailbox GUIDs and message UIDs without touching anything:

$ doveadm search -u [email protected] mailbox INBOX BEFORE 2026-10-01 SINCE 2026-09-01

An empty result means the filter matched nothing; treat that as information, not a reason to loosen the query. Search keys are case-insensitive, and multiple keys combine with AND by default, so the example above selects messages in INBOX with an internal date from 1 September 2026 through 30 September 2026. Dates and their exact semantics belong to the installed doveadm-search-query(7) manual; test a small known set first if a boundary matters, and remember that parentheses used with OR may need shell escaping.

3. Move messages for one user

Once the preview looks right, run the same query with move and the destination first:

$ doveadm move -u [email protected] Archive/2026 mailbox INBOX BEFORE 2026-10-01 SINCE 2026-09-01
$ printf 'exit status: %s\n' "$?"
exit status: 0

A successful run normally returns to the shell without any message, which is why the status check has to run immediately afterwards. Status 0 means the command completed; it does not mean the selection was the one you intended, so still check the destination and source mailboxes.

Recovery

If the selection turns out to be wrong, stop immediately, preserve the command and any logs, and use your Dovecot backup or restore procedure. Do not attempt a guessed reverse move.

4. Copy instead when the source must remain

copy takes the same arguments as move, but it does not expunge the source message:

$ doveadm copy -u [email protected] Archive/2026 mailbox INBOX BEFORE 2026-10-01 SINCE 2026-09-01
$ printf 'exit status: %s\n' "$?"
exit status: 0

Copy is the better first test when you are validating a destination, a filter, or a downstream workflow. It is still a state change: running it twice can duplicate messages in the destination. If that happens, recover by removing only the known duplicate messages using a separately verified selection, or restore from backup; never delete the whole destination mailbox to clean up.

5. Target several users deliberately

Use -u with a quoted wildcard when the scope genuinely covers many accounts:

$ doveadm copy -u '*@example.org' Archive/2026 mailbox INBOX FLAGGED
$ printf 'exit status: %s\n' "$?"
exit status: 0
  • Quote the wildcard. An unquoted mask gets expanded by the shell against local file names instead of reaching Dovecot.
  • Use -F for a fixed batch instead. It reads one username per line from a file, which is easier to audit than a mask:
$ sed -n '1,5p' /secure/path/users.txt
[email protected]
[email protected]
$ doveadm copy -F /secure/path/users.txt Archive/2026 mailbox INBOX FLAGGED

Review the file immediately before running the command. -A iterates every user found in the configured user databases, which can include system users when a passwd user database is in use; for SQL or LDAP, the iteration settings must match the user database or some accounts will be silently skipped. Prefer an explicit file whenever you need an auditable scope.

6. Use a source user only when the identity boundary is valid

The optional user SOURCE_USER form applies the query to a different user's mail location:

$ doveadm copy -u [email protected] Archive/2026 user [email protected] mailbox INBOX ALL

The installed manual documents a real limitation here: the user selected by -u and SOURCE_USER must currently share the same UID and GID. Do not assume two addresses are interchangeable; confirm the account mapping and access policy first, especially when moving mail between tenants or namespaces.

7. Verify the result

Run a read-only status check for both mailboxes using the same user:

$ doveadm mailbox status -u [email protected] messages unseen INBOX Archive/2026
INBOX messages=...
Archive/2026 messages=...
  • After a move. Repeat the original search against INBOX and confirm the intended matches are gone.
  • After a copy. Confirm the source still holds them and the destination shows the expected increase.
  • If another process is delivering mail. Counts can shift while you are checking them, so read the numbers as a snapshot.

Tip

Add -v for progress output on a large run, -D only while diagnosing a failure, and -S to point the command at a local socket or a remote hostname:port when your Dovecot administration setup requires it.

Done means

  • Version checked. The installed doveadm and dovecot-core match the examples you followed.
  • Destination confirmed. The mailbox existed before you ran the operation.
  • Preview run. A read-only search matched the exact query and account scope you intended.
  • Right verb chosen. copy was used when the source had to remain, move only after weighing its destructive effect.
  • Scope deliberate. Wildcards, -F, and -A were treated as decisions, not convenient defaults.
  • Result verified. The exit status and both mailbox states were checked after the command ran.