Corruption des boîtes mail Dovecot : procédures de récupération minimisant les dégâts

Cet article vous a aidé ?

Vous le remarquez d’abord comme une impression. Les utilisateurs se plaignent de comptes non lus fantômes, de dossiers affichant des messages « fantômes », de recherches qui mentent, ou d’Outlook qui se bloque sur « Synchronisation… » indéfiniment. Puis vos logs deviennent piquants : « Corrupted index », « UID validity changed », « Mailbox GUID mismatch », « Internal error occurred ». Vous avez une corruption de boîte mail, et chaque clic risque de transformer une réparation évitable en perte de données totale.

Il s’agit d’un playbook orienté production pour récupérer des boîtes mail Dovecot en minimisant les dégâts. Il est volontairement direct : l’indécision, c’est comme « réparer » la seule copie de la boîte du directeur financier avec une suppression récursive.

Un modèle mental pratique : ce que « corruption » signifie dans Dovecot

Dovecot n’est pas un « magasin de mail » monolithique. C’est un ensemble de comportements superposés sur votre format de stockage choisi (Maildir, mdbox, sdbox) plus des métadonnées (index, caches, listes UID), plus des fonctionnalités optionnelles (quota, recherche plein-texte), plus le comportement des clients (IMAP IDLE, CONDSTORE, QRESYNC).

La corruption de boîte mail dans Dovecot signifie généralement une des trois choses suivantes :

  1. Les métadonnées ne correspondent pas à la réalité. Les fichiers d’index indiquent que le message X existe, mais le fichier ou l’enregistrement sous-jacent n’existe pas (ou l’inverse). La plupart des tickets « corruption » se trouvent ici.
  2. Le stockage sous-jacent est incohérent. Les noms de fichiers Maildir sont corrompus, dupliqués, partiellement écrits ; ou la map/log de mdbox est désynchronisée ; ou le système de fichiers a renvoyé des données partielles/stagnantes. C’est là que « minimiser les dégâts » compte le plus.
  3. La vue du client est incompatible avec ce que le serveur affirme maintenant. Changement de UIDVALIDITY, réinitialisations de modseq, erreurs « unknown UID ». Le serveur peut avoir raison, mais il faut quand même gérer les conséquences côté client.

Ce qu’il ne faut pas faire : traiter la corruption comme un seul bug avec une seule solution. C’est un décalage entre des couches. Votre travail est d’identifier quelle couche ment, puis de forcer une réconciliation contrôlée dans la direction la plus sûre.

Direction la plus sûre par défaut : privilégier le stockage des messages sous-jacent comme source de vérité, puis reconstruire les métadonnées. Mais si le stockage sous-jacent est endommagé, il faudra prendre un snapshot, copier ce qui est lisible et reconstruire le magasin à partir des messages extraits.

Autre point : la « corruption » est souvent juste le symptôme d’autre chose : basculements de stockage, antivirus scannant en place, sémantiques de FS réseau boguées, ou un script de migration trop astucieux.

Une citation qu’il vaut la peine d’afficher : (idée paraphrasée) « L’espoir n’est pas une stratégie » — souvent attribuée dans les cercles ops à des ingénieurs comme Gene Kranz. En réparation de boîtes mail, l’espoir c’est comment on écrase la dernière bonne copie.

Playbook de diagnostic rapide (premier/deuxième/troisième)

C’est l’ordre qui vous mène le plus vite au goulot d’étranglement, avec le moins d’auto-infligé.

Premier : confirmer le périmètre et si des écritures ont lieu

  • Est-ce un seul utilisateur, une seule boîte, ou tout le système ?
  • Les clients écrivent-ils encore (nouveaux messages, IMAP APPEND, changements de flags) ?
  • Voyez-vous des erreurs actives du système de fichiers ou du disque ?

Si des écritures sont en cours et que le magasin est instable, vous ne « réparez » pas, vous jouez. Geler ou isoler.

Deuxième : classifier la défaillance par signature de log

  • Index/caches : « Corrupted index file », « cache file is corrupted », « index header mismatch ». Généralement réparable par reconstruction des index.
  • UID/UIDVALIDITY : « UIDVALIDITY changed », « Invalid UIDNEXT », « uidlist corruption ». Impact client plus fort, mais souvent reconstruction des métadonnées.
  • Couche de stockage : « read() failed », « Short read », « mbox map corrupted », « mdbox: rebuild failed », « Invalid message size ». Là, il peut s’agir de dommages réels sur les données.

Troisième : décider de la posture de récupération

  1. Réparation non destructive : snapshot/sauvegarde, arrêter les écritures, reconstruire les index, forcer la resynchronisation.
  2. Reconstruction contrôlée : exporter ce qui est lisible (ou dsync depuis une réplique), construire une boîte propre, réimporter.
  3. Mode forensique : conserver tout, faire une copie et travailler sur la copie quand des enjeux légaux/compliance sont en jeu.

Avant de toucher quoi que ce soit : règles de sécurité qui évitent les dégâts

La récupération de boîtes mail est une de ces tâches où l’outil fera exactement ce que vous avez demandé, pas ce que vous vouliez. Votre directive première est d’éviter de transformer une incohérence locale en suppression irréversible.

Règle 1 : geler les écritures ou isoler la boîte

Reconstruire les métadonnées pendant que la boîte est modifiée conduit à des corruptions répétées, à des déplacements de UIDNEXT et à des clients qui ne convergent jamais. Pour un utilisateur, vous pouvez désactiver temporairement sa connexion ou le rediriger vers un hôte de maintenance. Pour un backend complet, vous pouvez arrêter brièvement IMAP/LMTP ou vider le proxy.

Règle 2 : prendre un snapshot/sauvegarde du répertoire de la boîte (et des index)

Oui, les index aussi. Parfois l’index « corrompu » contient la seule carte vers un fichier message qui a été renommé ou égaré, surtout avec des migrations partielles.

Règle 3 : travailler sur une copie quand le magasin peut être endommagé

Si le système de fichiers renvoie des erreurs, ne lancez pas de commandes de réparation agressives sur la seule copie. Clonez le volume, ou au moins rsync l’arborescence des boîtes vers un stockage sain.

Règle 4 : préférer la reconstruction plutôt que les « corrections chirurgicales »

Éditer à la main des fichiers d’index Dovecot, c’est l’équivalent d’éditer un fichier de base de données avec un éditeur hexadécimal parce que « c’est plus rapide ». Ce n’est ni rapide ni sûr.

Petite blague #1 : La corruption de boîte mail, c’est comme les paillettes : on croit l’avoir nettoyée, puis elle apparaît encore dans vos logs pendant trois semaines.

Faits et contexte historique (pourquoi ces défaillances existent)

  • Les fichiers d’index de Dovecot sont une optimisation, pas la source de vérité. Ils existent pour rendre l’IMAP rapide : recherches rapides, tri, threading et cache.
  • Maildir a été conçu pour des livraisons concurrentes sûres en s’appuyant sur les sémantiques de nom de fichier, mais il suppose un système de fichiers fournissant rename atomique et opérations de répertoire cohérentes.
  • UIDVALIDITY d’IMAP est un contrat avec les clients. Le changer autorise les clients à considérer la boîte comme différente ; certains resynchronisent, d’autres dupliquent, d’autres s’énervent.
  • « dsync » est né des besoins de réplication de Dovecot et est maintenant un outil de réparation utile car il force une vue cohérente en réexaminant le magasin.
  • mdbox/sdbox existent principalement parce que Maildir « un fichier par message » n’est pas toujours gentil avec les disques (pression d’inodes, montée en charge des répertoires, surcharge de sauvegarde). Ils échangent la simplicité du FS contre la cohérence gérée par Dovecot.
  • Beaucoup de rapports de corruption sont en réalité des bugs de sémantique de stockage — en particulier les systèmes de fichiers réseau qui ne se comportent pas comme des systèmes POSIX locaux lors de rename/fsync.
  • Dovecot a historiquement été pointilleux sur le versioning des index. Les mises à niveau peuvent déclencher des reconstructions d’index ; mélanger des binaires anciens et nouveaux sur les mêmes index peut créer de la confusion.
  • Les index de recherche plein-texte (FTS) sont séparés des index de boîte mail et peuvent être erronés alors que le mail est intact. Les utilisateurs appellent souvent cela « mails manquants ». Il s’agit généralement de « résultats de recherche manquants ».

Ce ne sont pas des excuses. Ce sont des indices. Les modes de défaillance sont façonnés par des décennies d’attentes IMAP et par la vérité inconfortable que l’e-mail est un système distribué avec des contraintes.

Triage selon le format de stockage : Maildir vs mdbox/sdbox

Maildir : vos messages sont des fichiers

Avec Maildir, la corruption signifie souvent des incohérences de répertoire et de nom de fichier :

  • Des messages existent dans tmp/ qui n’ont jamais été déplacés vers new/ ou cur/.
  • Noms de fichiers dupliqués ou noms de base non uniques (généralement à cause d’un agent de livraison cassé).
  • Clients et serveur ne sont pas d’accord sur les flags parce que les noms de fichiers encodent les flags, et les caches de métadonnées prennent du retard.
  • Des problèmes de système de fichiers provoquent des écritures partielles ou des bizarreries d’entrées de répertoire.

Posture de récupération : préserver l’arborescence, puis reconstruire les indexes/caches Dovecot. Si les fichiers message sont endommagés, il faudra extraire.

mdbox/sdbox : vos messages sont des enregistrements, Dovecot gère les maps

Avec mdbox, les messages sont stockés dans des fichiers plus volumineux, et Dovecot utilise des mappings/index pour localiser les enregistrements. La corruption peut se manifester par :

  • Map/index désaccord : les métadonnées pointent vers un enregistrement qui ne se parse pas.
  • Corruption du log ou de la map après un arrêt non propre ou un incident de stockage.
  • Événements de disque plein qui tronquent une écriture en plein milieu d’un enregistrement.

Posture de récupération : être conservateur. Prendre un snapshot d’abord. Reconstruire les métadonnées avec les outils Dovecot ; éviter de « réparer » en supprimant des fichiers aléatoires dans dovecot.index* à moins de comprendre le format et la portée.

Tâches pratiques : commandes + signification de la sortie + décision à prendre

Ce sont les tâches que j’exécute réellement. Chacune inclut ce qu’il faut rechercher et quelle décision elle entraîne. Ajustez les chemins pour votre installation et votre base d’utilisateurs.

Task 1: Identify the failing mailbox and error signature

cr0x@server:~$ sudo journalctl -u dovecot --since "2 hours ago" | egrep -i "corrupt|uidvalidity|uidnext|index|mdbox|sdbox|short read|internal error" | tail -n 30
Jan 03 10:41:12 mx1 dovecot[2219]: imap(user@example.com)<11234>: Error: Mailbox INBOX: Corrupted index file /var/vmail/example.com/user/dovecot.index: Header size mismatch
Jan 03 10:41:14 mx1 dovecot[2219]: imap(user@example.com)<11234>: Error: Mailbox INBOX: UIDVALIDITY changed (14211 -> 18602)

Signification : Vous avez une signature de corruption d’index, plus un changement de UIDVALIDITY (ou au moins Dovecot pense qu’il a changé). C’est probablement du domaine de la reconstruction des métadonnées, mais vous devez arrêter les écritures ou risquer des oscillations.

Décision : Mettre la boîte affectée en mode maintenance (bloquer la connexion ou rediriger l’utilisateur), puis prendre un snapshot avant les réparations.

Task 2: Confirm Dovecot version and storage backend

cr0x@server:~$ dovecot --version
2.3.19.1
cr0x@server:~$ doveconf -n | egrep -i "mail_location|mail_driver|mail_home|namespace inbox|mail_plugins"
mail_location = maildir:/var/vmail/%d/%n
mail_plugins = quota fts fts_lucene

Signification : C’est Maildir, et vous avez quota + FTS. Attendez-vous à des problèmes séparés de FTS et à la nécessité de recalculer les quotas après réparation.

Décision : Planifier la reconstruction des index de boîte d’abord ; reconstruire les index FTS seulement après que le mail soit cohérent.

Task 3: Verify filesystem health signals (don’t repair on a dying disk)

cr0x@server:~$ dmesg -T | egrep -i "ext4|xfs|btrfs|zfs|I/O error|blk_update_request|nvme|ata|sense" | tail -n 20
[Fri Jan  3 10:35:22 2026] EXT4-fs warning (device sdb1): ext4_end_bio:342: I/O error 10 writing to inode 928381 (offset 0 size 4096 starting block 1234567)

Signification : Vous avez des erreurs d’E/S en écriture. Si vous reconstruisez des index maintenant, vous risquez d’écrire encore plus de métadonnées sur un système de fichiers défaillant.

Décision : Stopper. Stabiliser le stockage d’abord : basculer, remonter en lecture seule si nécessaire, ou restaurer depuis un snapshot/réplica.

Task 4: Check free space and inode availability (classic silent killer)

cr0x@server:~$ df -h /var/vmail
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       2.0T  1.9T   12G 100% /var/vmail
cr0x@server:~$ df -i /var/vmail
Filesystem     Inodes   IUsed   IFree IUse% Mounted on
/dev/sdb1     61054976 61054912     64  100% /var/vmail

Signification : Disque plein et pas d’inodes. Maildir se cassera de façons étonnantes car il ne peut pas créer de nouveaux fichiers pour les livraisons ou les reconstructions d’index.

Décision : Libérer de l’espace/inodes d’abord, puis s’occuper de la corruption. Sinon vous « réparerez » dans un état pire.

Task 5: Snapshot/backup the mailbox directory before changes

cr0x@server:~$ sudo rsync -aHAX --numeric-ids --info=progress2 /var/vmail/example.com/user/ /srv/recovery-snapshots/example.com/user-2026-01-03/
...output...

Signification : Vous avez maintenant une copie ponctuelle que vous pouvez comparer et restaurer. Si rsync renvoie des erreurs, c’est en soi un signal d’intégrité de stockage.

Décision : Si rsync rapporte des erreurs de lecture, passer en mode forensique : cloner le système de fichiers et éviter tout écrit supplémentaire.

Task 6: Verify mailbox list and basic access with doveadm (read-only check)

cr0x@server:~$ sudo doveadm mailbox list -u user@example.com | head
INBOX
Sent
Drafts
Trash
Archive

Signification : Dovecot peut énumérer les boîtes. Si cela échoue avec des erreurs internes, la corruption peut être plus large qu’un seul dossier.

Décision : Si la liste échoue, suspecter la configuration des namespaces, les permissions, ou une corruption sévère des index ; planifier une reconstruction plus large des index.

Task 7: Check mailbox status for inconsistent counters

cr0x@server:~$ sudo doveadm mailbox status -u user@example.com messages unread uidvalidity uidnext highestmodseq vsize INBOX
messages=842 unread=19 uidvalidity=18602 uidnext=901 highestmodseq=120044 vsize=188392012

Signification : Vous obtenez une ligne de statut cohérente. Si uidnext est inférieur au nombre de messages ou si des erreurs apparaissent, vous aurez probablement besoin d’une resynchronisation.

Décision : Si les compteurs UID semblent incorrects, planifier doveadm force-resync après sauvegarde et gel des écritures.

Task 8: Force a mailbox resync (metadata rebuild without deleting mail)

cr0x@server:~$ sudo doveadm force-resync -u user@example.com INBOX
cr0x@server:~$ sudo doveadm mailbox status -u user@example.com messages unread uidvalidity uidnext INBOX
messages=842 unread=19 uidvalidity=18602 uidnext=902

Signification : Dovecot a réexaminé le stockage et reconstruit les métadonnées clés. UIDNEXT a changé d’un, ce qui peut être normal après réconciliation.

Décision : Si des erreurs persistent, reconstruire explicitement les index (tâche suivante) et vérifier les dommages du système de fichiers.

Task 9: Rebuild Dovecot indexes for a user (aggressive but common)

cr0x@server:~$ sudo doveadm index -u user@example.com -q INBOX
cr0x@server:~$ sudo doveadm index -u user@example.com -q '*'

Signification : Recrée les données d’index. L’option -q réduit le bruit ; vérifiez les logs pour tout message « corrupt » durant l’indexation.

Décision : Si l’indexation déclenche « read() failed » ou « Short read », considérez cela comme un dommage de stockage/message, pas seulement des métadonnées.

Task 10: Remove only index/cache files (last resort, but sometimes necessary)

cr0x@server:~$ sudo find /var/vmail/example.com/user/ -maxdepth 2 -type f -name "dovecot.index*" -o -name "dovecot-uidlist" -o -name "dovecot-uidvalidity" -o -name "dovecot.list.index*" -print
/var/vmail.example.com/user/dovecot-uidlist
/var/vmail.example.com/user/dovecot.index
/var/vmail.example.com/user/dovecot.index.cache
cr0x@server:~$ sudo mv /var/vmail/example.com/user/dovecot.index /var/vmail.example.com/user/dovecot.index.bak
cr0x@server:~$ sudo mv /var/vmail/example.com/user/dovecot.index.cache /var/vmail.example.com/user/dovecot.index.cache.bak
cr0x@server:~$ sudo mv /var/vmail/example.com/user/dovecot-uidlist /var/vmail.example.com/user/dovecot-uidlist.bak

Signification : Vous avez supprimé des fichiers de métadonnées afin que Dovecot soit forcé de les recréer à partir de Maildir. Cela peut modifier les UIDs et agacer les clients, mais c’est souvent le réinitialisation la plus propre.

Décision : Faites cela seulement après sauvegarde et après arrêt des écritures. Si les clients prennent en charge QRESYNC, attendez-vous à une resynchronisation ; sinon, attendez-vous à des téléchargements plus lourds.

Task 11: Detect “stranded” Maildir messages in tmp/ (delivery interrupted)

cr0x@server:~$ sudo find /var/vmail/example.com/user/Maildir/tmp -type f | head
/var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
cr0x@server:~$ sudo find /var/vmail/example.com/user/Maildir/tmp -type f | wc -l
17

Signification : Des messages coincés dans tmp/ peuvent être invisibles aux clients. Ils peuvent être à moitié écrits, ou simplement jamais renommés à cause d’un disque plein ou d’un crash.

Décision : Inspecter quelques fichiers (taille, en-têtes). S’ils sont sains, vous pouvez les déplacer prudemment vers new/ ; sinon, conserver pour la forensique et ne pas injecter de données corrompues.

Task 12: Inspect a suspicious message file without mutating it

cr0x@server:~$ sudo ls -lh /var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
-rw------- 1 vmail vmail 2.0K Jan  3 10:30 /var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
cr0x@server:~$ sudo head -n 20 /var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
Return-Path: <sender@example.net>
Delivered-To: user@example.com
Received: by mx1 with LMTP id 7xYk...; Fri, 03 Jan 2026 10:30:41 +0000
Date: Fri, 03 Jan 2026 10:30:40 +0000
From: Sender <sender@example.net>
To: user@example.com
Subject: test
Message-ID: <...>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8

Signification : Cela ressemble à un message RFC 5322 valide. Bon signe.

Décision : S’il est valide, vous pouvez le déplacer vers new/ (avec les permissions correctes) et resynchroniser. Si les en-têtes sont manquants/garbled, garder en quarantaine.

Task 13: Safely move stranded tmp messages into new/ (only after confirming)

cr0x@server:~$ sudo sh -c 'for f in /var/vmail/example.com/user/Maildir/tmp/*; do test -f "$f" && mv -n "$f" /var/vmail/example.com/user/Maildir/new/; done'
cr0x@server:~$ sudo doveadm force-resync -u user@example.com INBOX

Signification : Les messages sont maintenant découvrables. L’option -n empêche l’écrasement en cas de collision de nom.

Décision : S’il y a des collisions, arrêter et investiguer pourquoi les noms de fichiers ne sont pas uniques — probablement un agent de livraison cassé ou un snapshot restauré mélangé.

Task 14: Recalculate quota (after repairs; quotas can lie)

cr0x@server:~$ sudo doveadm quota get -u user@example.com
Quota name=User quota Type=STORAGE Value=2048M Limit=2048M %
cr0x@server:~$ sudo doveadm quota recalc -u user@example.com
cr0x@server:~$ sudo doveadm quota get -u user@example.com
Quota name=User quota Type=STORAGE Value=1460M Limit=2048M %

Signification : Avant le recalcul, le système de quota pouvait compter des messages qui n’étaient pas réellement présents (ou manquer des messages présents). Après recalc, il correspond à la réalité.

Décision : Si les utilisateurs signalent « boîte pleine » après réparation, lancer quota recalc. Ne pas simplement augmenter les limites ; cela masque de vrais problèmes de stockage.

Task 15: Diagnose FTS confusion (search broken, mail fine)

cr0x@server:~$ sudo doveadm fts rescan -u user@example.com INBOX
cr0x@server:~$ sudo doveadm fts optimize -u user@example.com

Signification : Le FTS est reconstruit séparément. Cela résout les cas où « la recherche ne trouve pas le mail que je vois ».

Décision : Ne faire ceci qu’après stabilisation des index de boîte ; sinon vous indexez des données corrompues deux fois.

Task 16: Use dsync as a “truth enforcer” (great with replicas)

cr0x@server:~$ sudo doveadm dsync -u user@example.com backup -R -f /var/vmail/example.com/user/ "remote:replica-user@example.com"
dsync(user@example.com): info: Sync: mailbox INBOX: 842 messages, 0 expunges, 2 flag changes

Signification : Dsync réconcilie les différences entre deux magasins. En mode backup, il privilégie le côté local comme source de vérité ; inverser la direction avec précaution.

Décision : Si le magasin local est endommagé et la réplique saine, lancer dsync dans le sens qui écrase le local avec la réplique, mais seulement après avoir snapshoté le local endommagé.

Petite blague #2 : La deuxième chose la plus dangereuse sur un serveur mail est un « correctif rapide ». La première est un « correctif rapide » lancé en root sans snapshot.

Listes de contrôle / plan étape par étape (récupération minimisant les dégâts)

Choisissez le chemin qui correspond à votre situation. L’erreur est de traiter toutes les corruptions comme une reconstruction d’index.

Plan A: Index corruption only (most common, least scary)

  1. Confirmer l’étendue. Est-ce une boîte ou plusieurs ? Utiliser les logs et doveadm mailbox status.
  2. Geler les écritures pour cette boîte. Bloquer temporairement la connexion de l’utilisateur ou le déplacer vers un backend de maintenance.
  3. Prendre un snapshot/sauvegarde du répertoire. Inclure les fichiers cachés et dovecot.*.
  4. Exécuter une resync. doveadm force-resync -u user@example.com INBOX
  5. Reconstruire les index. doveadm index -u user@example.com -q '*'
  6. Recalculer le quota. Si vous utilisez les quotas : doveadm quota recalc
  7. Reconstruire le FTS si les utilisateurs se plaignent de la recherche.
  8. Lever le gel des écritures et surveiller les logs. Si les erreurs réapparaissent immédiatement, arrêter et vérifier le stockage/la livraison.

Plan B: Maildir directory inconsistencies (tmp/new/cur mess)

  1. Geler les écritures. Les livraisons et modifications IMAP doivent être en pause pour cette boîte.
  2. Sauvegarder l’intégralité du Maildir. Vous voulez préserver la version désordonnée.
  3. Compter les fichiers tmp coincés. Si ce sont quelques-uns, inspecter ; si ce sont des milliers, vous avez un problème systémique de livraison/fsync.
  4. Valider un échantillon de fichiers tmp. Vérifier les en-têtes et la plausibilité des tailles.
  5. Déplacer les fichiers tmp valides vers new/ en évitant l’écrasement.
  6. Supprimer/reconstruire les index. Mettre de côté dovecot.index* et dovecot-uidlist, puis resynchroniser.
  7. Message aux utilisateurs pour la récupération. Demander aux utilisateurs de redémarrer leurs clients ; certains retéléchargeront les en-têtes. Si UIDVALIDITY change, prévenir du risque de duplications chez certains clients.

Plan C: Underlying store damage suspected (I/O errors, short reads, truncated records)

  1. Arrêter les écritures immédiatement. Si possible remonter le magasin mail en lecture seule ou basculer.
  2. Obtenir une copie octet-à-octet ou un snapshot. Travailler sur la copie.
  3. Tenter des reconstructions non destructives de Dovecot sur la copie d’abord. Si elles échouent avec des erreurs de lecture, ne pas continuer à réessayer.
  4. Extraire les messages lisibles. Pour Maildir, copier les fichiers intacts. Pour mdbox, utiliser les outils Dovecot pour exporter si possible.
  5. Restaurer depuis une réplique/sauvegarde pour les parties manquantes. Dsync peut aider à réconcilier.
  6. Monter un magasin de boîte propre. Importer les messages extraits dans une nouvelle boîte puis basculer les clients.
  7. Post-mortem de l’événement de stockage. Corriger la cause racine : disque, contrôleur, sémantiques FS réseau ou planification de capacité.

Plan D: Replica exists and seems healthy (the “use the second copy” plan)

  1. Vérifier les signaux de santé de la réplique. Confirmer que la réplique peut servir la boîte sans erreurs.
  2. Snapshotter les deux côtés. Oui, même le bon. Les erreurs de réplication peuvent être des catastrophes symétriques.
  3. Choisir la direction délibérément. Si le primaire est corrompu, préférer la réplique comme source de vérité.
  4. Lancer dsync dans le bon mode. Faire des tests petits sur une boîte d’abord.
  5. Valider les comptes de messages et contrôler un échantillon de mails récents.
  6. Réactiver le trafic normal et surveiller.

Erreurs courantes : symptôme → cause → correctif

1) Symptom: “Missing emails” but only search is broken

Root cause : Corruption ou latence de l’index FTS ; la boîte est intacte.

Fix : Lancer doveadm fts rescan pour les utilisateurs/boîtes affectés après stabilisation des index de boîte.

2) Symptom: UIDVALIDITY changed; clients duplicate or re-download everything

Root cause : Suppression/recréation de dovecot-uidvalidity ou reconstruction forcée qui a réinitialisé UIDVALIDITY ; ou boîte recréée pendant une migration.

Fix : Éviter de supprimer UIDVALIDITY sauf si nécessaire. Si cela a déjà changé, communiquer les étapes aux clients ; pour les clients récalcitrants, supprimer et réajouter le compte peut être nécessaire.

3) Symptom: Rebuilding indexes “works” but corruption returns daily

Root cause : Problème de sémantique de stockage sous-jacent (FS réseau, antivirus, outil de sauvegarde modifiant les fichiers), erreurs disque, ou churn d’espace.

Fix : Examiner dmesg, options de montage et processus tiers qui touchent les fichiers. Corriger l’environnement, puis reconstruire une seule fois.

4) Symptom: Many messages stuck in tmp/ and new deliveries intermittently missing

Root cause : Disque plein / épuisement d’inodes / crash pendant la livraison / comportement LMTP/LDA cassé.

Fix : Résoudre la capacité. Puis valider et déplacer tmp vers new, suivi d’un force-resync.

5) Symptom: “Internal error occurred. Refer to server log” on mailbox open

Root cause : Mismatch de permissions/ownership après restauration, ou index créés par le mauvais UID, ou héritage ACL cassé.

Fix : Vérifier l’ownership du système de fichiers et les attentes de Dovecot pour mail_uid/mail_gid ; corriger les permissions, puis reconstruire les index.

6) Symptom: mdbox mailbox shows sudden gaps, “Invalid message size”

Root cause : Fichier mdbox tronqué à cause d’un disque plein ou d’une erreur d’E/S pendant l’écriture.

Fix : Snapshotter, tenter une reconstruction/export Dovecot sur une copie, restaurer les messages manquants depuis réplique/sauvegarde. Ne pas « rm des fichiers au hasard ».

7) Symptom: One folder broken, others fine; error mentions dovecot.list.index

Root cause : Corruption de l’index de liste de boîtes, parfois après arrêt brutal ou mélange de binaires de versions différentes.

Fix : Mettre de côté dovecot.list.index* pour l’utilisateur, puis laisser Dovecot régénérer en listant les boîtes et en resynchronisant.

8) Symptom: Repairs cause message flag chaos (read/unread flips)

Root cause : Flags Maildir dans les noms de fichiers qui divergent du cache ; ou clients qui mettent en cache l’état et réappliquent des changements après reconnexion.

Fix : Reconstruire les index ; puis laisser une fenêtre de stabilisation. Pour des utilisateurs clés, recommander de redémarrer les clients après la réparation côté serveur.

Trois mini-récits d’entreprise depuis le terrain

Mini-story 1: The incident caused by a wrong assumption

Une entreprise de taille moyenne faisait tourner Dovecot avec Maildir sur un système de fichiers réseau. L’équipe supposait que « ce sont juste des fichiers » signifiait qu’il se comporterait comme un disque local. Ça a fonctionné pendant des mois, ce qui est la façon dont les suppositions deviennent des « faits ».

Puis une fenêtre de maintenance est arrivée : un basculement de stockage, un bref blocage, et une poignée de clients qui n’ont jamais cessé de synchroniser. Lundi matin : des utilisateurs ont signalé des messages manquants dans Sent, mais seulement dans certains sous-dossiers. Les logs montraient des corruptions d’index intermittentes et parfois des « short read ».

La réponse initiale fut prévisible : reconstruire les index pour les utilisateurs affectés, un par un. Cela a aidé quelques heures, puis les mêmes boîtes « se sont corrompues » de nouveau. Quelqu’un a tenté une approche plus agressive — supprimer dovecot.* sur l’ensemble — parce que cela avait marché une fois en labo. Cela a déclenché des changements de UIDVALIDITY pour un lot de boîtes, et les clients ont répondu en retéléchargeant, dupliquant, et transformant le service support en spectacle.

La cause racine n’était pas Dovecot. Le FS réseau n’honorait pas de façon fiable les sémantiques rename+fsync attendues lors du basculement. Maildir dépend de ces opérations pour présenter une transition atomique « le message apparaît ». Sous stress, les transitions tmp/new devenaient bizarres, et les index Dovecot n’étaient que le messager.

Ils ont corrigé cela en déplaçant le stockage mail sur le disque local des nœuds mail et en utilisant une réplication correcte au niveau Dovecot. Les reconstructions d’index ont cessé d’être un rituel quotidien. La leçon : un système qui « se comporte généralement comme POSIX » n’est pas identique à POSIX quand l’iPhone du CEO fait 20 opérations IMAP par seconde.

Mini-story 2: The optimization that backfired

Une autre organisation souhaitait des sauvegardes plus rapides et moins d’inodes. Maildir semblait « inefficace », ils ont donc migré vers mdbox. C’était une décision d’ingénierie raisonnable avec un coût caché : la mémoire opérationnelle de l’équipe était basée sur Maildir, et leurs runbooks restaient « juste déplacer des fichiers ».

Ils ont aussi optimisé pour la vitesse : cache agressif et FTS très sollicité. Tout était rapide, jusqu’à un événement disque plein pendant un pic d’ingestion. Disque plein n’est pas spectaculaire quand il arrive ; c’est ennuyeux, puis tout devient dramatique ensuite.

Après l’événement, un sous-ensemble d’utilisateurs ne pouvait plus ouvrir leur INBOX. Les logs contenaient « Invalid message size » dans mdbox, et les reconstructions d’index n’ont pas résolu le problème. Quelqu’un a tenté de supprimer ce qui semblait être « juste des index » dans le répertoire mdbox. Cela a empiré car ils ont supprimé des fichiers de mapping qui n’étaient pas de simples caches.

La récupération a fonctionné, mais elle a exigé de la discipline : snapshotter ce qui restait, restaurer depuis une réplique quand possible, et exporter/importer les messages lisibles pour le reste. Leur optimisation a fourni des performances, mais elle a demandé plus de rigueur en surveillance de capacité et une meilleure compréhension des fichiers essentiels vs métadonnées.

La leçon : les optimisations de performance sont bien. Mais chaque optimisation a un coût opérationnel. Si vous ne le payez pas progressivement (surveillance, runbooks, formation), vous le paierez d’un coup pendant un incident.

Mini-story 3: The boring but correct practice that saved the day

Une entreprise régulée faisait tourner Dovecot avec réplication et une politique stricte « snapshot avant mutation ». Ce n’était pas glamour. Cela signifiait aussi que l’équipe d’astreinte avait une réponse initiale plus lente, parce que chaque runbook commençait par « geler, snapshotter, vérifier ».

Un jour, un lot de boîtes a commencé à jeter des erreurs d’index après un événement d’alimentation non propre. Les utilisateurs criaient ; la direction criait plus fort. Le SRE de garde a suivi la checklist ennuyeuse : isoler une boîte, snapshotter, tenter force-resync, reconstruire les index, puis vérifier avec quelques commandes doveadm status.

Pour les quelques boîtes qui échouaient encore, ils n’ont pas cherché à forcer. Ils ont immédiatement basculé ces utilisateurs vers la réplique, puis ont utilisé dsync pour réconcilier une fois le primaire stable. Pas d’éditions manuelles. Pas de suppressions au hasard. Pas de boucles « essayer et voir ».

Parce qu’ils avaient des snapshots avant chaque mutation, ils ont pu annuler quelques tentatives maladroites d’un ingénieur junior sans drame. Les auditeurs ont ensuite demandé comment ils garantissaient l’intégrité pendant la récupération. La réponse était ennuyeuse, précise et correcte : snapshots immuables plus reconstructions contrôlées. C’est le genre d’ennuyeux qui protège vos weekends.

FAQ

1) Should I delete dovecot.index to fix corruption?

Parfois, oui — mais seulement après une sauvegarde/snapshot et après avoir arrêté les écritures pour cette boîte. Préférez doveadm force-resync et doveadm index d’abord. Supprimer les fichiers d’index peut provoquer des oscillations d’UID/flags et de la douleur côté client.

2) Will doveadm force-resync delete messages?

Il est conçu pour réconcilier les métadonnées avec le magasin sous-jacent, pas pour supprimer des mails. Mais si votre magasin sous-jacent manque des messages auxquels les index faisaient référence, le « résultat » est que ces messages n’apparaissent plus. Ce n’est pas une suppression par la commande ; c’est la réalité qui est reconnue.

3) Users say mail is gone, but I can see files in Maildir. Why?

Dovecot peut ne pas les voir à cause d’une corruption d’index, de problèmes de permissions, ou parce qu’ils sont coincés dans tmp/. Valider ownership et emplacement, puis resynchroniser.

4) How do I handle UIDVALIDITY changes with minimal client chaos?

Éviter de les déclencher inutilement. Si elles sont arrivées, communiquer clairement : les clients peuvent retélécharger ou dupliquer. Encourager les utilisateurs à redémarrer leurs clients ; pour les duplications persistantes, supprimer et réajouter le compte est souvent la réinitialisation cliente la plus propre.

5) Is Maildir “safer” than mdbox for corruption?

Maildir est plus simple à inspecter et à récupérer au niveau fichier. mdbox peut être plus efficace et cohérent sous forte charge mais exige plus de respect pour les métadonnées gérées par Dovecot. « Plus sûr » dépend de si votre équipe comprend le format et si votre stockage se comporte correctement.

6) Can antivirus or backup agents cause mailbox corruption?

Oui. Tout ce qui modifie, verrouille, renomme, ou lit/écrit partiellement des fichiers message et des métadonnées dovecot peut créer des incohérences. L’échec classique est un agent qui scanne in-place et entre en concurrence avec la livraison ou les mises à jour d’index.

7) What’s the difference between mailbox index issues and FTS issues?

Les index de boîte affectent le contenu des dossiers, les flags et les opérations IMAP de base. Le FTS affecte les résultats de recherche. Les utilisateurs signalent fréquemment des pannes FTS comme des « mails manquants » parce qu’ils recherchent plutôt que de naviguer.

8) Should I run repairs while the server is live?

Pas si vous pouvez l’éviter. Pour une seule boîte, on peut parfois s’en sortir, mais l’approche la plus sûre est de geler les écritures pour la portée affectée. Réparer pendant que des clients martèlent la boîte, c’est obtenir des résultats non répétables.

9) How do I know if corruption is caused by the filesystem?

Rechercher des erreurs d’E/S dans dmesg, des avertissements du système de fichiers, et des échecs rsync/lecture lors de la copie des maildirs. Si les erreurs coïncident avec des événements de stockage (basculement, disque plein, pics de latence), considérer le stockage comme le suspect principal.

10) After a repair, why are unread counts wrong?

L’état non lu combine flags de message et état d’index/cache. Après reconstruction, les comptes peuvent changer pour refléter ce qui est réellement sur disque. Certains clients « réappliquent » aussi l’état mis en cache après reconnexion ; laisser une fenêtre de stabilisation.

Conclusion : prochaines étapes que vous pouvez faire aujourd’hui

La récupération de corruption de boîtes mail consiste surtout en discipline : arrêter les écritures, préserver les preuves, reconstruire les métadonnées depuis la source de vérité la plus sûre, puis seulement s’occuper des modules de performance comme le FTS. Quand vous sautez le snapshot ou ignorez la santé du stockage, vous transformez une réparation en réécriture de l’histoire.

Prochaines étapes pratiques :

  1. Ajouter une règle dans le runbook : « snapshot avant mutation » pour toute réparation de boîte mail.
  2. Instrumenter des alertes d’espace disque et d’inodes spécifiques au stockage mail ; disque plein est une usine à corruption.
  3. Décider à l’avance de votre politique « source de vérité » (primaire vs réplique) et documenter les choix de direction dsync.
  4. Auditer les agents tiers (antivirus, sauvegarde, indexation) qui touchent directement le magasin mail.
  5. Pratiquer sur une copie de staging : exécuter doveadm force-resync, doveadm index, recalcul de quota et reconstruction FTS pour que l’astreinte n’apprenne pas en pleine panne.

Si vous ne retenez rien d’autre : faites moins de choses, mais plus soigneusement. L’e-mail est patient ; vos utilisateurs, pas.

← Précédent
Interface modale Cmd+K : listes de résultats, indices clavier et états vides (approche HTML/CSS d’abord)
Suivant →
Générations Intel Core : comment décoder les noms sans perdre la tête

Laisser un commentaire