2026.10 / Maildir UIDs 079
Docker Mailserver Dovecot “Broken file dovecot-uidlist”
Dovecot logs Broken file .../dovecot-uidlist with details such as Invalid data, Broken header, UIDs not ordered, or UID larger than next_uid. The affected IMAP folder may fail to open, repeatedly resynchronise, or show confusing message state. In Docker Mailserver, this is a mailbox-control-file incident—not a reason to delete the mail-data volume.
The dovecot-uidlist file maps persistent IMAP UIDs to Maildir filenames. Dovecot can reconstruct a UID list from the message files, but reconstruction can change UID state and force clients to invalidate their local cache or download messages again. First preserve the mailbox and its metadata, identify why the file broke, and try Dovecot’s scoped repair path.
A disposable index cache and a Maildir UID list are not the same thing. Protectdovecot-uidlistbefore any repair, and never delete everydovecot*file recursively.
What dovecot-uidlist protects
Maildir stores messages as files under cur, new, and tmp. IMAP also needs a stable numeric UID for each message and a mailbox UIDVALIDITY value. Dovecot keeps that mapping in dovecot-uidlist. Clients use the combination of UIDVALIDITY and UID to recognise messages across sessions.
This creates two separate recovery goals:
- Preserve the actual message files and make the mailbox readable again.
- Preserve existing UID identity where possible so clients retain flags, cached bodies, and synchronisation state.
A regenerated file may satisfy the first goal while disrupting the second. That is why “just delete it” is a last resort, not the opening command.
| Evidence | Likely boundary | First response |
|---|---|---|
| One mailbox reports one malformed line | Interrupted or damaged UID-list update | Protect that mailbox and run a scoped resync |
Permission denied or lock-file errors | Ownership, traversal, mount, or host policy | Repair write access before touching metadata |
No space left on device | Blocks or inodes exhausted | Restore measured capacity first |
| Errors recur across several accounts | Filesystem, remote storage, or concurrent-writer problem | Stop writes and investigate storage-wide evidence |
| UIDVALIDITY changes after recovery | UID list was regenerated | Expect client resynchronisation; verify no duplicates or loss |
1. Capture the exact error and affected scope
Open the failing folder once while following a bounded log window:
docker compose logs --since 10m --follow mailserver
Record the first error, account, mailbox, line number, and any earlier I/O, locking, permission, capacity, or read-only-filesystem message. Keep the raw output private: mailbox names, addresses, host paths, and message identifiers can be sensitive.
Determine whether the failure affects one folder, every folder for one account, or many users. If the first error is instead Corrupted index cache file, use the separate Dovecot index-cache recovery guide. Different files have different consequences.
2. Confirm the live image, mailbox format, and mount
Do not assume the checked-in Compose file describes the running container. Capture runtime evidence:
docker inspect mailserver \
--format 'image={{.Config.Image}} id={{.Image}}'
docker inspect mailserver \
--format '{{range .Mounts}}{{println .Type .Source "->" .Destination .RW}}{{end}}'
docker compose exec mailserver dovecot --version
docker compose exec mailserver doveconf -n
Confirm that the mailbox is Maildir, that the expected persistent storage is mounted read-write at /var/mail, and that index or control files have not been redirected elsewhere. Keep host source paths and private configuration out of public reports.
This guide is specifically about Maildir. Dovecot’s dbox formats rely on their indexes differently; do not apply Maildir file-removal advice to sdbox or mdbox.
3. Prove storage can perform safe UID-list updates
Dovecot locks dovecot-uidlist for writes and may replace it using a rename operation. A repair will fail again if storage cannot create locks, append reliably, or rename atomically.
docker compose exec mailserver df -h /var/mail
docker compose exec mailserver df -i /var/mail
docker compose exec mailserver \
doveadm user [email protected]
Inspect host logs for filesystem errors, read-only remounts, abrupt shutdowns, storage latency, out-of-memory kills, and mandatory-access-control denials. On NFS or another remote filesystem, verify the documented locking and rename semantics for the actual Dovecot version and topology. Recurring malformed UID lists across nodes are evidence of a storage or concurrent-access problem, not many independent unlucky mailboxes.
If Dovecot cannot create dovecot-uidlist.lock, follow the mailbox permission guide first. Do not make mail world-writable to get past the lock.
4. Preserve messages and metadata before repair
For a production mailbox, stop or quiesce delivery and IMAP writes long enough to take a consistent backup. Preserve the pinned image reference, DMS configuration, mail-data storage, and the affected mailbox metadata. A bind-mounted reference-layout example is:
docker compose down
# This archive contains private mail; protect it accordingly.
sudo tar --numeric-owner -cpf \
mail-data-before-uidlist-repair.tar \
-C ./docker-data/dms mail-data
tar -tf mail-data-before-uidlist-repair.tar >/dev/null
For named volumes or large storage, use a documented volume backup or consistent snapshot. Verify that the protected copy contains the affected mailbox’s message directories and its original dovecot-uidlist. Store it with restrictive permissions away from the live volume.
The broader Docker Mailserver backup and restore runbook covers configuration, mail, state, image pinning, and restore drills.
5. Use Dovecot’s scoped repair first
After correcting any proven storage, capacity, permission, or mount fault, start the same pinned image and ask Dovecot to resynchronise only the affected mailbox:
docker compose up -d mailserver
docker compose exec mailserver \
doveadm force-resync -u [email protected] INBOX
Replace the placeholder address and mailbox privately. Dovecot documents force-resync for repairing mailboxes it cannot automatically fix. Start with one account and one folder; do not begin with an all-user operation.
Immediately capture the result and a fresh log window. If resync succeeds, continue to the UID and client checks below. If it fails, preserve the new error instead of repeating the command until evidence scrolls away.
6. If the UID list cannot be repaired in place
Only consider regeneration when all of these are true:
- The mailbox is confirmed as Maildir.
- The actual
curandnewmessage files are protected and readable. - The original UID list is backed up separately.
- The underlying storage fault has been corrected.
- A scoped
force-resyncstill cannot recover the mailbox. - The documentation for the pinned Dovecot version supports recreating this control file for this error.
Dovecot’s Maildir documentation warns that deleting control files can give messages new UIDs and lose keyword names. Its error guidance describes deleting dovecot-uidlist only as a way to recreate UIDs in specific otherwise-unrecoverable cases. If you reach that path, stop writes, move—not recursively delete—the one affected UID-list file into the protected incident directory, then let Dovecot reconstruct state for that one mailbox.
Do not publish or blindly copy a guessed filesystem command: Docker Mailserver account paths vary, mailbox folders have different on-disk names, and a typo can target the wrong user. Resolve the exact path from doveadm user, effective configuration, and the error itself.
7. Record UIDVALIDITY before and after
Before repair, if the mailbox still answers, record its status. Repeat after repair:
docker compose exec mailserver \
doveadm mailbox status -u [email protected] \
'messages unseen uidnext uidvalidity' INBOX
If UIDVALIDITY is unchanged and clients retain normal state, the repair likely preserved mailbox identity. If it changed, clients must treat prior UID mappings as invalid. That can cause a full resynchronisation and may look like duplicate downloading even when the server has one copy of each message.
Do not “fix” a changed UIDVALIDITY by editing numbers manually. Restoring inconsistent UID metadata can associate a UID with the wrong message. Either restore the complete known-good mailbox state or accept a controlled client resync after proving server-side message integrity.
8. Verify mail and client behaviour
A clean force-resync exit is not the acceptance test. Verify the affected folder end to end:
- Count server-side messages and compare them with the protected pre-repair evidence.
- Open several old and recent messages over IMAP.
- Deliver one controlled message and confirm it appears exactly once.
- Mark a disposable message read, flag it, move it, reconnect, and confirm state persists.
- Reconnect one existing client and observe whether it performs a normal incremental sync or a full resync.
- Check another unaffected mailbox as a negative control.
- Review logs for fresh UID-list, lock, I/O, permission, or index errors.
- Recreate the mail container once and repeat status plus delivery checks.
Keep the original UID list and full mailbox backup through the rollback window. If corruption returns after new delivery, stop treating the file as the root cause and investigate the storage and writer path.
Repairs to avoid
- Deleting the mail-data volume: the message files and control state live there.
- Deleting every
dovecot*file: UID lists, indexes, caches, transaction logs, subscriptions, and keyword maps are not interchangeable. - Editing a malformed UID-list line: a syntactically plausible file can still map UIDs to the wrong messages.
- Running a repair for every user first: it increases I/O and impact before one mailbox proves the method.
- Regenerating on unhealthy storage: the new file is likely to break again.
- Ignoring a UIDVALIDITY change: client redownloads are an expected protocol consequence that need monitoring.
- Broad recursive ownership changes: they can expose private mail and break delivery identities.
- Upgrading DMS during recovery: keep image migration separate from mailbox repair.
Compact recovery order
- Capture the exact broken-file detail, user, mailbox, and affected scope.
- Record the running image, Dovecot version, Maildir configuration, and live mount.
- Check blocks, inodes, write access, locking, host storage, and recent crashes.
- Quiesce writes and take a verified private backup including the original UID list.
- Correct the underlying storage or permission fault.
- Run
doveadm force-resyncfor one user and one mailbox. - Regenerate a UID list only as a documented last resort, with client impact understood.
- Verify counts, content, flags, moves, UIDVALIDITY, delivery, clients, logs, and recreation.
Authoritative references: Dovecot’s Maildir format documentation explains the UID-to-filename mapping, locking, append, and rename behaviour of dovecot-uidlist; its doveadm force-resync manual defines the scoped repair command; and its error reference describes UID recreation for exceptional Maildir failures. Docker Mailserver’s optional configuration guide documents its persistent storage boundaries. Match every command to the DMS and Dovecot versions and mailbox format you actually run.