Reset Attachment Flags with doveadm rebuild
Mail clients keep showing the wrong paperclip, and doveadm rebuild attachments is the command that resets Dovecot's attachment-presence indicator. You pick the messages with a search query, run it, then confirm which ones were processed. The examples use dovecot-core 2.3.21+dfsg1-2ubuntu6.5, whose manual page documents Dovecot 2.3 behaviour.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes for a small mailbox and longer for a broad query. You need a shell, Dovecot running, and permission to use the Dovecot administration socket.
- What it changes: mailbox metadata only.
- What it leaves alone: it does not move or delete messages.
- What it can cost: a broad run can touch a huge number of messages and eat storage and I/O.
1. Confirm the installed command
Check the package and command before choosing a scope. These checks are ordinary and read-only:
$ dpkg-query -W -f='${Package} ${Version}\n' dovecot-core
dovecot-core 1:2.3.21+dfsg1-2ubuntu6.5
$ command -v doveadm
/usr/bin/doveadm
$ doveadm help rebuild
rebuild attachments
Checkpoint
The installed command lists rebuild attachments. The help output can also include the global usage line, or an error from a local socket when Dovecot is not running.
The package version above is local to this host. Check yours rather than assuming that a later Dovecot release has the same global options.
2. Know what will change
doveadm rebuild attachments resets the attachment indicator for messages matching a search query and prints the UID of each match. It is an administrative, state-changing command, so do not start with -A on a production system just to see whether it works.
Recovery
There is no documented undo for this rebuild. Stop the command, check the scope, and rerun it with the intended query.
The message contents and mailbox locations are not the target, but schedule a large run for a quiet period and watch the service and storage metrics.
For a first run, select one user and a narrow query. Replace the example username and subject with values from your mailbox:
$ doveadm rebuild attachments -u USERNAME SUBJECT "EXACT SUBJECT TEXT"
17
42
In this example, UIDs 17 and 42 were the matching messages. Your output will differ. A blank result can be a successful run with no matching messages, so check the exit status immediately afterwards:
$ printf 'exit status: %s\n' "$?"
exit status: 0
Tip
Do not insert another command between doveadm and the status check. A zero status confirms that the command completed, not that the query matched a message.
3. Start narrow, then widen the query
The shortest valid search query is ALL. It selects every message in the chosen user's mailboxes, so it suits a deliberate mailbox-wide rebuild but is too broad for an initial test:
$ doveadm rebuild attachments -u USERNAME ALL
1
2
3
4
Queries can combine keys, and the default operator is AND. For example, this selects messages in the Trash mailbox that are older than the supplied date:
$ doveadm rebuild attachments -u USERNAME MAILBOX Trash BEFORE 2026-01-01
23
24
- Keys are case-insensitive.
subjectandSUBJECTbehave the same. - Quote values with spaces. That covers mailbox names and subjects.
- Review the query on its own. Confirm the username, mailbox and date before pressing Enter.
- Read the search-query manual. It documents other keys such as
FROM,SUBJECT,SEEN,LARGERandNOT.
4. Choose the user scope explicitly
With no user option, the manual says the command runs in the environment of the currently logged-in system user. That is not the same as selecting every Dovecot account. As an administrator, make the intended scope visible in the command line.
Use -u for one user or a wildcard mask. Quote a wildcard so that the shell does not expand it against local file names:
$ doveadm rebuild attachments -u 'USER*@example.org' SUBJECT "invoice"
[email protected] 8
[email protected] 31
When -u uses a wildcard, the output includes both the username and the UID. Verify that the account names are the ones you meant before treating the run as complete.
Use -F when you have an explicit, reviewed file containing one username per line:
$ sudo install -m 600 /dev/null /tmp/dovecot-users.txt
$ sudo sh -c 'printf "%s\n" [email protected] [email protected] > /tmp/dovecot-users.txt'
$ sudo doveadm rebuild attachments -F /tmp/dovecot-users.txt SUBJECT "invoice"
[email protected] 8
[email protected] 31
Read the file before running it:
$ sudo sed -n '1,20p' /tmp/dovecot-users.txt
The example needs elevated privileges only because it deliberately puts the list in a root-owned temporary path. A normal user-owned file works without sudo. If the list holds sensitive account data, remove it once you have checked the run:
$ sudo rm -- /tmp/dovecot-users.txt
5. Run all users only after a review
-A performs the command for every user returned by the user database iteration. That is potentially expensive and can hurt the service. Check the configured iteration behaviour first, and confirm that the result includes only real mail users:
$ sudo doveconf -n | sed -n '/^userdb/,/^}/p'
$ sudo doveadm rebuild attachments -A SUBJECT "invoice"
[email protected] 8
[email protected] 31
Warning
The manual specifically warns about userdb { driver = passwd }, where iteration can include system users below first_valid_uid.
- SQL user databases: check that
iterate_querymatches the database layout. - LDAP: check
iterate_attrsanditerate_filter. - Settings not right? Use a reviewed
-Ffile instead of trusting-A.
6. Add diagnostics without changing the selection
Use -v for a progress counter and -D for debug messages. Keep the same user scope and search query while you diagnose a problem:
$ sudo doveadm -v rebuild attachments -u USERNAME SUBJECT "EXACT SUBJECT TEXT"
17
42
The default output formatter is flow without a key prefix. You can ask for table, tab or pager with -f, but the plain default is usually easiest to capture and audit.
If a remote administration socket is intentionally configured, -S accepts either an absolute UNIX socket path or a hostname:port endpoint:
$ sudo doveadm -S /var/run/dovecot/doveadm-server rebuild attachments -u USERNAME ALL
Tip
Do not invent a socket path. Check the Dovecot configuration and its permissions first. A socket error is an access or service problem, not a reason to widen the command or retry against an arbitrary endpoint.
Done means
- Command checked. The installed package and
doveadmcommand were confirmed. - Scope reviewed. The username, search query and expected scope were checked before the state-changing run.
- Narrow test passed. It finished with a recorded exit status and understandable UID output.
- Careful with -A. It was used only after user database iteration and service impact were reviewed.
- Username file cleaned up. Any list was treated as sensitive temporary data and removed when no longer needed.
- Nothing lost. No message was deleted or moved, and you have a record of the query used.