Apache SpamAssassin is the spam filter cPanel already ships, and on most shared boxes it's left at defaults doing a mediocre job — either waving spam through or, worse, silently deleting invoices. It scores every inbound message against thousands of rules and RBL checks, then Exim acts on the score. Get the scoring and the disposition right and it quietly removes most of the junk. Get it wrong and you generate the two worst support tickets in hosting: "I'm drowning in spam" and "I never got the email."
This is for operators running mail on cPanel & WHM who want SpamAssassin doing real work without data loss. It covers the WHM-side forced settings, the threshold and disposition logic, SMTP-time rejection, and per-test score overrides — plus where the landmines are.
How Exim and SpamAssassin split the work
SpamAssassin only scores. Exim acts. Every inbound message is scanned, assigned a numeric spam score, and stamped with an X-Spam-Score header. What happens next — deliver, file to a folder, delete, or reject at SMTP time — is decided by the threshold and disposition settings below.
The default Spam Threshold Score is 5. A message scoring 5 or higher is marked spam. Lower is aggressive (more false positives), higher is passive (more spam through). Five is a sane middle; don't move it until you've watched real traffic.
Set the server-wide policy in WHM first
Individual cPanel users can tune their own filter, but the server-wide floor lives in WHM → Service Configuration → Exim Configuration Manager, on the Apache SpamAssassin and Basic Editor tabs. Set these before touching anything per-account:
- Apache SpamAssassin: Forced Global ON — turns scanning on for every account and prevents users from disabling it. On a shared box carrying reputation risk, force it on. If you leave it optional, expect a chunk of your accounts to never enable it and then complain about spam.
- Apache SpamAssassin message size threshold to scan — default 1000 KB. Messages larger than this are not scanned at all, which is a common spam-through gap for image-heavy junk. Raising it to 2000–5000 KB catches more at a modest CPU cost.
- Enable Apache SpamAssassin for secondary MX — if your server acts as a backup MX, turn this on or that path becomes an unscanned spam lane.
- Apache SpamAssassin rejects spam score threshold — the most useful setting most admins never touch. See below.
Reject the obvious junk at SMTP time
The rejects spam score threshold tells Exim to refuse a message with a 550 during the SMTP conversation once its score crosses a high bar — before it's ever accepted or stored. This is strictly better than accepting and deleting: the sending server gets a bounce (so real senders find out), you store nothing, and there's no folder to police.
Set it high — 12 or 15 — so only unambiguous spam is rejected. A message scoring 12+ is not a false positive in practice. Everything between your Spam Threshold (5) and this reject line still gets scanned and filed; only the egregious stuff is turned away at the door.
550 Message rejected as spam by Apache SpamAssassin
This is the single highest-ROI change on a busy mail server: it cuts storage, cuts the Spam folder review burden, and gives legitimate misfires a bounce instead of a black hole.
Spam Box vs auto-delete: choose deliberately
For everything above the Spam Threshold but below the reject line, there are two dispositions, set per account in cPanel → Email → Spam Filters:
- Spam Box — files flagged mail into a
spamIMAP folder. Nothing is lost; users (or you) can fish out false positives. It counts against the mailbox quota, so it needs occasional pruning. - Auto-Delete — permanently deletes messages at or above the Auto-Delete Threshold Score. This score is independent of the Spam Threshold. There is no recovery. A single misconfigured customer-facing rule here loses a real order.
The correct rollout is Spam Box first, auto-delete never — or only at a very high score:
Whitelist, blacklist, and per-test scoring
The per-account Spam Filters → Additional Configurations panel is where you fix specific misfires:
- Whitelist / Blacklist accept wildcards —
*@partner.comtrusts a whole domain,?matches a single character. Whitelist a sender SpamAssassin keeps flagging; blacklist a persistent nuisance the score won't catch. - Calculated Spam Score Settings let you override individual test weights. Set a noisy rule's score to
0to disable it, or raise the weight on a test that reliably fires on your spam. To see current test scores:
grep -R score /var/lib/spamassassin/ | less
Per-user overrides live in each account's preferences file:
/home/USERNAME/.spamassassin/user_prefs
You can edit required_score, whitelist_from, and individual score lines there directly. After any rule change, lint before you rely on it:
spamassassin --lint
A clean lint prints nothing. Errors mean a broken rule that will stop the daemon from loading — never skip this after hand-editing config.
Keep the rules current
SpamAssassin's accuracy decays as spammers adapt; stale rules are why an untended server slowly gets worse. cPanel runs sa-update on a schedule, but confirm it's actually pulling fresh rulesets:
sa-update --nogpg && echo "updated" || echo "no update / already current"
If you maintain custom global rules, keep them out of the vendor directories cPanel overwrites — put site-wide rules in /etc/mail/spamassassin/ and treat /var/lib/spamassassin/ as vendor-managed. Custom rules that live in the wrong place vanish on the next update.
When mail is delayed, not filtered
If the complaint is slow rather than missing, SpamAssassin usually isn't the cause — a saturated scanner or a backed-up queue is. Check the Exim queue for frozen or stuck messages first, and remember that spam handling is only half the reputation picture. Getting your own mail accepted elsewhere depends on SPF, DKIM, and DMARC, and a compromised account blasting spam will torch your IP faster than any inbound filter can protect it — cap it with outbound throttling.