Panellicense

Clear a frozen or stuck Exim mail queue on cPanel

A decision tree for a cPanel Exim queue that won't drain — tell frozen from deferred, find the compromised account, and clear messages without nuking real mail.

5 min readUpdated 2026-06-21exim · cpanel · mail-queue · frozen
schema: TechArticleschema: FAQPage

exim -bpc returns a five-figure number, mail is crawling, and the load average is climbing. The queue is backed up — but before you run the "delete everything" one-liner you found on a forum, work out why. A queue full of frozen bounces is a different problem from a queue full of deferred outbound spam, and clearing the wrong one either loses legitimate mail or papers over a compromised account that refills the queue in minutes.

This is the triage order for a cPanel box where Exim won't drain. For stopping the outbreak in the first place, see Exim outbound throttling; this article assumes the queue is already on fire.

Step 1: size the queue and split it by state

exim -bpc                    # total messages
exiqgrep -c -z               # frozen only
exiqgrep -c -r '.'           # count by recipient regex (sanity check)

A message is frozen when Exim has given up retrying — almost always a bounce with no valid return path (<> sender). It is deferred when delivery failed but Exim will retry on schedule. The split tells you which branch to follow:

  • Mostly frozen, sender <> → bounce backscatter. Usually safe to purge (Step 3).
  • Mostly deferred to remote domains, one local sender → outbound spam from a compromised account (Step 2). Do not purge first.
  • Deferred to your domains → a real delivery problem (full disk, broken /etc/localdomains, MySQL down). Fix the cause; don't delete mail.

Step 2: find the account flooding the queue

Before clearing anything, identify the top senders. If one account owns most of the queue, you have a compromise, not a backlog.

# Top authenticated senders / auth IDs in the queue
exim -bpr | grep -oP '(?<=<)[^>]+(?=>)' | sort | uniq -c | sort -rn | head

# Who is sending right now, by directory / script
grep cwd /var/log/exim_mainlog | grep -v /var/spool | awk '{for(i=1;i<=NF;i++) if($i ~ /cwd=/) print $i}' | sort | uniq -c | sort -rn | head

The cwd= line points straight at the offending site's document root — that is the WordPress install or PHP script doing the sending.

Step 3: clear the queue selectively

Match the command to what you found. Always prefer the narrowest filter that solves the problem.

# Remove only frozen messages (safe for backscatter bounces)
exiqgrep -z -i | xargs -r exim -Mrm

# Remove messages from one sender
exiqgrep -f '^baduser@example\.com$' -i | xargs -r exim -Mrm

# Remove messages older than 3 days (259200 seconds)
exiqgrep -o 259200 -i | xargs -r exim -Mrm

Only when you've confirmed the queue is entirely junk should you reach for the nuclear option:

# Delete EVERY message in the queue — irreversible
exim -bp | awk '/<[^@]+@/{print $3}' | xargs -r exim -Mrm

Step 4: verify the queue actually drains

After clearing, watch the count fall and confirm it stays down:

watch -n5 'exim -bpc'

If the count climbs again, Step 2 missed the source — recheck cwd= in the live log. A queue that refills after a clean purge is a compromise, full stop. Run a malware scan (Imunify360 Proactive Defense catches most PHP mailers) and rotate the account's passwords.

Step 5: clean up the queue database

A queue that hit six figures leaves a bloated retry/wait hints database that slows every delivery. Compact it during a quiet window:

exim_tidydb -t 7d /var/spool/exim retry
exim_tidydb -t 7d /var/spool/exim wait-remote_smtp

If Exim itself is wedged and ignoring signals, /scripts/restartsrv_exim restarts the daemon cleanly on cPanel without touching your config.

What is the difference between a frozen and a deferred Exim message?+
A deferred message failed delivery but Exim will retry it on its retry schedule. A frozen message is one Exim has stopped retrying — typically a bounce with an empty (<>) sender that has nowhere to go. Frozen bounces are usually safe to delete; deferred mail to your own domains may be legitimate.
How do I delete all frozen messages in cPanel Exim?+
Run exiqgrep -z -i | xargs -r exim -Mrm. The -z flag selects frozen messages only, -i prints their IDs, and exim -Mrm removes each one. This leaves deferred and in-flight mail untouched.
Why does my Exim queue fill up again right after I clear it?+
Almost always a compromised account or a vulnerable PHP script sending spam. Grep the exim_mainlog for cwd= to find the sending directory, suspend that account, then clear the queue. Clearing without stopping the source just repeats the cycle.
Is it safe to delete the whole Exim mail queue?+
Only when you have confirmed every message is junk — deletion is irreversible and takes any legitimate queued mail with it. If the backlog is real mail stuck behind a transient failure, fix the cause and run exim -qff to retry instead of deleting.
How do I count how many messages are in the cPanel mail queue?+
exim -bpc prints the total count. exiqgrep -c -z counts only frozen messages, which is the fastest way to tell a backscatter problem from an outbound-spam problem.

Next steps

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.