Resolving mailbox quota conflicts and SMTPUTF8 errors in exim/dovecot#
During large-scale email migrations between control panels (such as cPanel to Plesk, or vice versa), two issues occur with high frequency: discrepancies between actual disk usage of mailboxes and the limits shown in the administrative panel, and outbound delivery failures bearing the SMTPUTF8 used when not advertised error string.
By addressing both problems together, we restore operational stability to the SMTP server (MTA) and the local Dovecot quotas.
1) Initial diagnosis and version verification#
Before making changes to any configuration files, verify the versions of the primary packages involved to map configuration syntax compatibilities:
# Check Exim version
exim -V
# Check Dovecot version
doveadm --version
# Get the installed cPanel/WHM version
cat /usr/local/cpanel/version
2) Inconsistent mailbox quota conflicts#
Common Symptoms:
- The control panel UI indicates a "mailbox full" state, but the physical disk has ample free storage space.
- The user is unable to send or receive emails due to a quota limit error, but the physical directory size is well below the defined limit.
A. Physical disk measurement via shell (maildir)#
Verify the actual footprint of the mailbox directly on the server's disk:
# Display the size of all mailboxes under a domain
du -h --max-depth=1 /home/user/mail/domain.com/ | sort -h
B. Check active Dovecot quotas#
Query the active quota metrics in Dovecot's memory for the affected account:
# Get quota limits for a specific user
doveadm quota get -u [email protected]
If the results from du and doveadm quota get show a significant difference, the maildirsize index file is stale or corrupted.
C. Verify quota configuration in Dovecot#
Make sure the quota plugin is loaded and check active quota limits. If you need to check or customize quota rules post-migration, inspect the quota_rule directives in Dovecot's configuration files (usually /etc/dovecot/conf.d/90-quota.conf):
# Validate that the quota plugin is enabled in mail_plugins
doveconf -n | grep -i "mail_plugins"
# Check global quota limits and rules
doveconf quota_rule
3) Quota remediation workflow (runbook)#
Step a: complete backup of maildirsize files#
# Create a backup directory
BACKUP_DIR="/root/maildirsize-backup-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# Find and copy maildirsize files while preserving the folder hierarchy
find /home/user/mail/domain.com/ -name "maildirsize" -exec cp --parents {} "$BACKUP_DIR/" \;
# Alternative: Create a compressed tar.gz file of all maildirsize files
find /home/user/mail/domain.com/ -name "maildirsize" -exec tar czf "$BACKUP_DIR/maildirsize-backup.tar.gz" {} +
echo "Complete backup of quotas saved to: $BACKUP_DIR"
Step b: remove obsolete quota files#
Delete the stale maildirsize files to force Dovecot to regenerate clean index configurations:
find /home/user/mail/domain.com/ -name "maildirsize" -exec rm -f {} \;
Step c: forcing a real-time recalculation#
Instruct Dovecot to recount disk usage based on the actual physical directory scan:
# Recalculate quota for a specific email box
doveadm quota recalc -u [email protected]
# Recalculate quotas for all mailboxes in a domain in batch using secure globbing (avoids ls)
for dir in /home/user/mail/domain.com/*/; do
mailbox="$(basename "$dir")"
doveadm quota recalc -u "[email protected]"
done
Step d: synchronize the control panel cache (cPanel specific)#
If the server uses cPanel, update the panel's internal cache database to match the corrected storage state on disk:
/scripts/update_db_cache
Step e: post-recalculation verification#
Validate that the disk footprint and Dovecot metrics now match, and run a delivery test:
# Compare quota query output with physical disk usage
doveadm quota get -u [email protected]
du -sh /home/user/mail/domain.com/contact/
# Monitor Dovecot logs for quota warnings (traditional syslog)
tail -n 50 /var/log/maillog | grep -i "quota"
# Alternative log query using journalctl on systemd systems
journalctl -u dovecot --since "1 hour ago" | grep -i "quota"
# Send a test email to verify mailbox limits
echo "Email quota test message" | mail -s "Quota Test" [email protected]
4) SMTPUTF8 delivery failure#
The Error: SMTPUTF8 used when not advertised
Root Cause: This occurs when the sending client utilizes the SMTPUTF8 extension (RFC 6531) to transmit headers containing non-ASCII characters, but the destination SMTP server (MTA) does not announce SMTPUTF8 support in the initial handshake (EHLO). Because the destination cannot handle UTF-8 envelopes, the connection is rejected at source.
A. Diagnosing the Exim queue#
Inspect and monitor messages deferred due to SMTPUTF8 failures:
# Search Exim logs for SMTPUTF8 errors
grep -i "smtputf8" /var/log/exim_mainlog | tail -n 50
# Alternative log query via journalctl on systemd systems
journalctl -u exim --since "2 hours ago" | grep -i "smtputf8"
# Alternative path check if physical files differ (ex: Debian/Ubuntu)
grep -i "smtputf8" /var/log/exim/mainlog | tail -n 20
# List active messages in the Exim queue
exim -bp
Understanding exim -bp Output:#
Active messages in the queue list are shown as: 12h 1.8K 1abcde-0001ab-ab <[email protected]> [email protected]
- Column 1: Time message has spent in the queue (e.g.,
12hfor 12 hours). - Column 2: Message size (e.g.,
1.8K). - Column 3: Unique message ID (e.g.,
1abcde-0001ab-ab). - Column 4: Sender and recipient addresses.
To count and filter messages stuck in the queue:
# Count total messages in the queue
exim -bp | wc -l
# Filter messages stuck for more than 24 hours
exim -bp | awk '$1 ~ /d$/ {print}' | head -n 20
B. Verify SMTPUTF8 configuration in Exim#
# Check if Exim is advertising the smtputf8_advertise_hosts directive
exim -bP smtputf8_advertise_hosts
# Search the configuration file for the directive
grep -i "smtputf8" /etc/exim.conf
Note: In cPanel/WHM, you can query this setting using the API:
whmapi1 listeximconfig | grep -i smtputf8
5) Resolving SMTPUTF8 errors in Exim#
If your mail server needs to send emails containing UTF-8 headers to legacy remote servers that do not support the extension, you should configure Exim to disable the forced SMTPUTF8 advertisement, allowing for standard fallback.
Navigate to WHM » Exim Configuration Manager » Advanced Editor, search for smtputf8_advertise_hosts, and set its value to empty.
Apply the changes, validate syntax, and restart Exim:
# Restart the Exim service
systemctl restart exim
Clearing the queue of stuck messages#
To force-delete messages delayed due to repeated SMTPUTF8 handshake rejections:
# 1. Inspect headers/body of a specific queued message before purging
exim -Mvh MESSAGE_ID
# 2. Safely audit SMTPUTF8 message details in batch
exim -bp | grep -i "smtputf8" | awk '{print $3}' | while read -r msgid; do
echo "=== MSG ID: $msgid ==="
exim -Mvh "$msgid" | head -15
echo -e "-------------------------\n"
done
# 3. Remove messages stuck with the SMTPUTF8 error from the queue (after verification)
exim -bp | grep -i "smtputf8" | awk '{print $3}' | xargs -r exim -Mrm
# 4. Force immediate delivery attempt for a specific domain only (safer route)
exim -qff -R @troublesome-destination-domain.com
# Alternative: Force global delivery queue flush with caution
# Note: `-qff` (flush frozen) attempts delivery of both active and frozen messages,
# while `-qf` (normal flush) only retries active messages. In unstable environments,
# prefer `-qf` or `-qff -R @domain` to limit the scope of the delivery attempt.
exim -qff
SOP: email migration checklist (quota + SMTPUTF8)#
Follow this operational flow to audit and stabilize email systems during migrations:
Pre-migration#
- [ ] Back Up Dovecot Quotas: Export current limit values:
doveadm quota get -A > /root/quota-original.txt - [ ] Back Up maildirsize Files: Create a compressed archive of all mail directories.
- [ ] Verify SMTPUTF8 Settings: Check configuration status on the source server:
exim -bP smtputf8_advertise_hosts - [ ] Disk Space: Verify capacity and free inodes on the destination host:
df -handdf -i
During migration#
- [ ] Synchronize email files preserving all permissions and ownership attributes (
rsync -avzorimapsync) - [ ] Copy
maildirsizefiles temporarily for validation.
Post-migration#
- [ ] Remove Stale maildirsize: Delete migrated index files (especially when migrating using
imapsync) to prevent cache conflicts. - [ ] Recalculate Quotas: Force recounting of mailbox sizes in Dovecot:
doveadm quota recalc -A(and verify customized rules viaquota_rule). - [ ] Tune Exim: Configure
smtputf8_advertise_hoststo handle connections to legacy destination hosts. - [ ] Audit System Logs: Monitor
/var/log/exim_mainlog,/var/log/maillog, or query viajournalctlfor delivery issues.
Acceptance & validation#
- [ ] Cross-check disk size footprint against Dovecot data (
du -shvsdoveadm quota get). - [ ] Confirm the control panel UI displays correct quota values.
- [ ] Run a test SMTP message delivery check for both new and migrated boxes.
Email quota and queue audit script#
Use this audit-quota.sh script to regularly audit mailboxes and report queue issues:
#!/bin/bash
# audit-quota.sh - Email Quota and Exim SMTP Queue Auditing
# Usage: ./audit-quota.sh
set -euo pipefail
echo "=========================================================="
echo " RUNNING EMAIL QUOTA AND EXIM QUEUE AUDIT"
echo "=========================================================="
# 1. Check software versions
echo -e "\n[1] Component Versions:"
exim -V | head -n 1
doveadm --version 2>/dev/null || echo "Dovecot: $(dovecot --version)"
# 2. Check Exim queue status
echo -e "\n[2] Exim Queue Status:"
QUEUE_COUNT=$(exim -bp | grep -c '^[0-9]' || true)
echo " Stuck messages in queue: $QUEUE_COUNT"
if [ "$QUEUE_COUNT" -gt 0 ]; then
echo " Latest 5 queue items:"
exim -bp | head -n 10
fi
# 3. Search for stale maildirsize files
echo -e "\n[3] maildirsize Files Unmodified for Over 30 Days:"
find /home/*/mail -name "maildirsize" -mtime +30 2>/dev/null | head -n 15 || echo " No old maildirsize files found."
# 4. Check for quota errors in Dovecot logs
echo -e "\n[4] Recent Quota Error Logs (Dovecot):"
grep -i "quota" /var/log/maillog 2>/dev/null | tail -n 5 || echo " No recent quota logs found in syslog."
# 5. Check for SMTPUTF8 errors in Exim logs
echo -e "\n[5] Recent SMTPUTF8 Errors (Exim):"
grep -i "smtputf8" /var/log/exim_mainlog 2>/dev/null | tail -n 5 || echo " No recent SMTPUTF8 logs found."
# 6. Check Exim SMTPUTF8 advertisement configuration
echo -e "\n[6] Exim smtputf8_advertise_hosts Configuration:"
exim -bP smtputf8_advertise_hosts 2>/dev/null || echo " Directive not found in Exim's active configuration."
echo -e "\n=========================================================="
echo " AUDIT COMPLETED"
echo "=========================================================="
Production takeaways#
Post-migration quota mismatches and SMTPUTF8 errors are typically caused by obsolete index files (maildirsize) and MTAs requiring modern encoding configurations not supported by legacy destinations. By backing up index tables prior to purging them, recalculating disk usage via the Dovecot CLI, and configuring appropriate host options in Exim, we safely restore email services back to peak performance.
Was this article helpful?
Leave a quick reaction to help prioritize future technical guides:
This post is licensed under CC BY-NC.



Comments
Join the discussion below.
0 comments