← Back home

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. Protect dovecot-uidlist before any repair, and never delete every dovecot* 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:

  1. Preserve the actual message files and make the mailbox readable again.
  2. 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.

EvidenceLikely boundaryFirst response
One mailbox reports one malformed lineInterrupted or damaged UID-list updateProtect that mailbox and run a scoped resync
Permission denied or lock-file errorsOwnership, traversal, mount, or host policyRepair write access before touching metadata
No space left on deviceBlocks or inodes exhaustedRestore measured capacity first
Errors recur across several accountsFilesystem, remote storage, or concurrent-writer problemStop writes and investigate storage-wide evidence
UIDVALIDITY changes after recoveryUID list was regeneratedExpect 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:

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:

  1. Count server-side messages and compare them with the protected pre-repair evidence.
  2. Open several old and recent messages over IMAP.
  3. Deliver one controlled message and confirm it appears exactly once.
  4. Mark a disposable message read, flag it, move it, reconnect, and confirm state persists.
  5. Reconnect one existing client and observe whether it performs a normal incremental sync or a full resync.
  6. Check another unaffected mailbox as a negative control.
  7. Review logs for fresh UID-list, lock, I/O, permission, or index errors.
  8. 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

Compact recovery order

  1. Capture the exact broken-file detail, user, mailbox, and affected scope.
  2. Record the running image, Dovecot version, Maildir configuration, and live mount.
  3. Check blocks, inodes, write access, locking, host storage, and recent crashes.
  4. Quiesce writes and take a verified private backup including the original UID list.
  5. Correct the underlying storage or permission fault.
  6. Run doveadm force-resync for one user and one mailbox.
  7. Regenerate a UID list only as a documented last resort, with client impact understood.
  8. 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.