If contact form emails are showing up six hours late, or a client says their invoice never arrived, the first place to check isn't the inbox - it's the Exim mail queue on your server. A backed-up or frozen queue is one of the most common reasons mail "goes missing" without ever actually bouncing.
Symptom: mail is delayed, or WHM warns about queue size
You'll usually spot this one of two ways:
- WHM shows a yellow or red banner like "The Exim mail queue contains N messages" on the main dashboard.
- Outgoing mail from a WordPress site, a script, or a mailbox takes hours to arrive - or never arrives, with no bounce notice either.
Check the queue size directly over SSH before you do anything else:
exim -bpcThat prints just the count. Anything under a few dozen on a small VPS is usually normal churn. Hundreds or thousands is a problem worth digging into.
Cause: why messages pile up or freeze
"Queued" and "frozen" are not the same thing, and the fix is different for each:
- Deferred (queued, still retrying) - the receiving mail server is temporarily unreachable, slow, or greylisting the connection. Exim will keep retrying automatically for up to 2-4 days depending on your
exim.confretry rules. This is normal and usually self-resolves. - Frozen - Exim gave up retrying, often because of a permanent SMTP error (bad recipient domain, DNSSEC/DNS failure, "relay not permitted," or the recipient server hard-rejecting the sender IP). Frozen messages sit there forever until someone thaws, retries, or deletes them.
- Compromised account or script - by far the most common cause of a suddenly huge queue. A hacked WordPress install or an old contact form script starts blasting spam, and either your outbound traffic gets throttled by the recipient side, or your own server's rate limits (Exim ACLs, CSF, cPanel's Email Deliverability settings) start deferring the flood.
- Local delivery stuck - if the message is addressed to a mailbox on your own server, it can freeze because the mailbox is over quota, Dovecot isn't running, or the maildir has permission issues.
Fix: inspect the queue before you touch it
Don't mass-delete yet. First find out what's actually in there and why.
1. Summarize the queue by sender domain
exiqsummThis groups messages by domain and shows counts and average age. If one domain (especially your own) dominates the list, that's your starting point - it usually points straight at a compromised account or a runaway cron job.
2. Filter for just the frozen messages
exiqgrep -z -i-z matches frozen messages, -i prints just the message IDs so you can pipe them into other commands.
3. Read why a specific message is stuck
exim -Mvl <message-id>This shows the delivery log for that one message - the actual SMTP error from the last attempt. That error tells you whether it's worth retrying (temporary DNS or connection issue) or safe to bin (permanent "no such user" or "relay denied").
4. Act on what you find
| Situation | Command |
|---|---|
| Retry a frozen message now | exim -M <message-id> |
| Thaw frozen messages so they queue-run normally | exim -Mf <message-id> |
| Remove one bad message | exim -Mrm <message-id> |
| Remove every frozen message from a specific domain | exiqgrep -z -i -f spammydomain.com | xargs exim -Mrm |
| Force a full queue run right now | exim -qff |
On a cPanel/WHM server you can do most of this without SSH too: go to WHM > Email > Queue Manager. It lists every message with sender, recipient, size, and age, and gives you buttons to deliver, freeze/thaw, or delete - handy if you just want to clear a handful of stuck items visually.
5. If it's a compromised account, stop the source first
Clearing the queue without fixing the cause just refills it. If exiqsumm pointed at one of your own domains sending hundreds of messages you didn't send:
- Check WHM > Email > Email Deliverability and cPanel > Email > Track Delivery for the account to see which script or mailbox is the actual sender.
- Scan the site for a compromised plugin, an old unused contact-form script, or a leaked SMTP password - see our guide on cleaning up a hacked WordPress site if it's WordPress.
- Reset any mailbox or database passwords tied to the account before you clear the queue, or the flood restarts within minutes.
Prevention: catch a backing-up queue before WHM's banner does
- Set a cron job to alert you if the queue crosses a threshold:
[ $(exim -bpc) -gt 200 ] && echo "Queue high" | mail -s "Exim queue alert" you@yourdomain.com. - In WHM, enable Email > Exim Configuration Manager > Advanced Editor rate limits (
smtp_ratelimit) so a single compromised script can't flood the queue silently. - Keep WHM > Email > Email Deliverability green for every domain - a missing SPF/DKIM record makes legitimate outbound mail far more likely to defer or bounce, which inflates the queue on its own.
- Review cron-driven mail (WP-Cron notifications, backup scripts, monitoring alerts) - a misconfigured cron that emails on every run is a quieter but very common source of slow queue growth.
- On a VPS, watch
/var/spool/exim/msglogdisk usage too - a queue that's growing but never clearing can eventually fill the partition Exim itself needs to operate.
Most queue problems clear up within a queue run or two once the underlying cause - a down recipient server, a bad DNS record, or a compromised script - is gone. What you don't want to do is exim -Mrm the whole queue blind; you'll silently drop real customer emails along with the spam.