majorwiki/05-troubleshooting/networking/dovecot-imap-oom-vsz-limit-bloated-index.md
MajorLinux 26eb13ab2f troubleshooting: document majormail client-connectivity incident (2026-06-05)
- 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.
2026-06-05 14:04:22 -04:00

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
dovecot
imap
oom
vsz_limit
index
maildir
fedora
mail
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 .Later folder had a 152 MB dovecot.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 -h shows 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/ and new/ 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.j2default_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.
  • tcpdump may 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.