- New page: Dovecot IMAP vsz_limit OOM from a bloated/corrupt index.log (152M index on an empty folder killed IMAP children with error 83). - fail2ban IMAP self-ban: add permanent ignoreip-whitelist fix + dynamic-IP caveat. - firewalld mail ports: add 'submission/587 never added' variant + correct Fedora service name; note Ansible now manages the full mail-service set. - Index + SUMMARY updated with the new page.
5.4 KiB
| title | domain | category | tags | status | created | updated | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Dovecot IMAP Clients Fail to Sync: vsz_limit OOM from a Bloated Index Log | troubleshooting | networking |
|
published | 2026-06-05 | 2026-06-05 |
Dovecot IMAP Clients Fail to Sync: vsz_limit OOM from a Bloated Index Log
All IMAP clients fail to connect or hang while syncing a particular folder, even though the box has plenty of free RAM and disk. The cause is a corrupt/bloated per-folder dovecot.index.log that overflows Dovecot's per-process virtual-memory cap (default_vsz_limit, 256 MB by default) when it is mmaped — so the IMAP child is killed on every sync attempt.
First seen on majormail (Fedora 44, Dovecot 2.4.4), 2026-06-05. An empty
.Laterfolder had a 152 MBdovecot.index.log.
Symptoms
- Multiple/all IMAP clients can't connect, or connect but never finish syncing.
- Often only one folder is the trigger — the client hangs the moment it opens/syncs that folder.
- The server is otherwise healthy: Postfix delivering, Dovecot
active, ports listening, TLS valid. free -hshows the host has plenty of RAM available — this is not a host-level OOM.
Log Signature
journalctl -u dovecot shows, per affected user/folder:
imap(user@dom): Fatal: block_alloc(8388608): Out of memory
imap(user@dom): Fatal: master: service(imap): child NNN returned error 83
(Out of memory (service imap { vsz_limit=256 MB }, you may need to increase it) ...)
imap(user@dom): Error: Mailbox X: mmap(size=158769660) failed ...: Cannot allocate memory
imap(user@dom): Error: Mailbox X: Failed to map transaction log .../dovecot.index.log
at sync_offset=N after locking: Beginning of the log isn't available
The two tells: error 83 naming vsz_limit (Dovecot literally suggests raising it), and an mmap(size=…) value that is huge relative to the folder's real contents.
Why It Happens
Each Maildir folder has its own dovecot.index.log transaction log. If it grows or corrupts to tens/hundreds of MB (here: 152 MB on a folder with zero messages), Dovecot tries to mmap the whole thing into the IMAP worker. That worker runs under default_vsz_limit (compiled default 256 MB). The mapping blows the cap, the kernel refuses the allocation, and the child dies with error 83. Because every client re-syncs that folder on connect, it fails for all of them at once.
Key point: the limit is per-process virtual size, not host memory. A box with 2.5 GB free RAM still hits it.
Diagnosis
# 1. The smoking gun — OOM / error 83 mentioning vsz_limit
journalctl -u dovecot --since "-3h" | grep -iE "out of memory|error 83|vsz_limit"
# 2. Confirm it is NOT a host OOM (expect plenty free)
free -h ; df -h /var/vmail
# 3. Current per-process cap (256 M = compiled default, no explicit setting)
doveconf default_vsz_limit
# 4. Find the bloated index — size wildly out of proportion to message count
du -sh /var/vmail/<domain>/<user>/.<Folder>
ls -lh /var/vmail/<domain>/<user>/.<Folder>/dovecot.index*
ls -1 /var/vmail/<domain>/<user>/.<Folder>/{cur,new} | wc -l # real message count
Fix
Two parts: raise the cap, and repair the bloated index.
# (1) Raise default_vsz_limit. Flat Fedora dovecot.conf has no !include conf.d/*,
# so add it at top-level scope (after `protocols = ...`):
# default_vsz_limit = 1G
doveconf -n >/dev/null && echo CONFIG_OK # validate
systemctl restart dovecot # required to apply the new vsz
doveconf default_vsz_limit # -> 1G
# (2a) Rebuild the index from the real messages
doveadm force-resync -u <user@dom> <Folder>
# (2b) If force-resync leaves a stale multi-MB index.log AND the folder has
# 0 message files, it is safe to delete the index files and let Dovecot
# regenerate them clean (152 M -> 24 K in the original case):
L=/var/vmail/<domain>/<user>/.<Folder>
rm -f $L/dovecot.index $L/dovecot.index.log $L/dovecot.index.cache $L/dovecot.index.backup
doveadm mailbox status -u <user@dom> "messages vsize" <Folder> # regenerates
Verify: journalctl -u dovecot --since "-2m" | grep -ic "out of memory" returns 0, and the folder reads without error.
Only delete index files when the folder's
cur/andnew/are empty (or you are certain the messages are intact). The index is rebuildable from the message files; deleting indexes never deletes mail, but verify the count first.
Codified
majormail's role sets this permanently so the cap survives a config rebuild:
roles/majormail/templates/dovecot.conf.j2 → default_vsz_limit = 1G (MajorAnsible commit a69ac5d).
Key Notes
error 83= vsz, not host RAM. Don't go chasing free memory — read the parenthetical in the error; Dovecot names the exact setting.- A huge index on a tiny/empty folder is the corruption, not the messages. Resync, and truncate the index if the folder is empty.
tcpdumpmay not be installed on a minimal Fedora mail host — don't conclude "no packets arrived" from an empty capture without confirming the tool exists (which tcpdump).- 1 G is a comfortable headroom for large mailboxes; raise further only if a genuinely large single mailbox needs it.