What does the SpamAssassin rule FONT_INVIS_MSGID test for?

Michael Ko
Co-founder & CEO, Suped
Published 3 Jun 2025
Updated 27 May 2026
10 min read
Summarize with

The FONT_INVIS_MSGID rule tests for a combination of hidden or near-invisible HTML text and suspicious Message-ID context. It is not only a Message-ID syntax check, and it is not only an HTML styling check. SpamAssassin describes it as Invisible text plus suspicious message ID, which is accurate but too compressed for troubleshooting.
I read this rule as a correlation warning: the message body contains text that a human reader will not see, and the headers do not give SpamAssassin enough confidence that the Message-ID pattern belongs to a normal sender path. A valid-looking Message-ID can still be part of the hit if the rest of the message looks unusual.
What FONT_INVIS_MSGID tests for
In current SpamAssassin rule logic, FONT_INVIS_MSGID is a meta rule. A meta rule fires when lower-level tests fire together. In this case, one side looks for font-based invisible text in the raw HTML. The other side checks Message-ID and delivery context, then applies exceptions for common benign patterns. The public rule descriptions use the short description, but the real fix requires looking at both the body and the headers.
- Hidden HTML: Inline styles with tiny font sizes, zero-like units, or transparent color can satisfy the invisible text side.
- Header signal: The Message-ID pattern and surrounding delivery headers can make the message look less like ordinary mail.
- Benign exceptions: Known sender patterns, relay clues, campaign headers, and MIME details can suppress the published hit.
- Score impact: The rule commonly appears around a 2.5 score, enough to matter when other tests are already adding points.
Simplified rule logictext
__FONT_INVIS = hidden or transparent font text in HTML __FONT_INVIS_MSGID = __FONT_INVIS plus Message-ID context FONT_INVIS_MSGID = publish unless benign header clues apply
Do not fix only the Message-ID
If the Message-ID is syntactically valid, do not stop there. The rule name points at the Message-ID because that header is part of the correlation. The hidden text is usually the fastest thing to inspect and remove.
For a wider explanation of how individual SpamAssassin tests add up, the related page on SpamAssassin rule impact is useful when a single rule does not explain the final inbox result.
Why invisible text matters
Hidden text has a long spam-filter history because it can feed words to filters without showing those words to the reader. A spammer can hide neutral text, keyword stuffing, random words, or copied article fragments to change token analysis. Legitimate senders can also trigger the same pattern by accident, especially through email builders that add hidden preheader text, copied formatting, or conditional content.

Infographic showing hidden HTML plus Message-ID context causing a rule hit.
Common legitimate causes
- Preheader text: A hidden preview line added by the template builder or sending platform.
- Responsive blocks: Mobile or desktop variants hidden through CSS while another version is shown.
- Editor residue: Copied content that leaves transparent spans, empty font tags, or tiny fallback text.
- Tracking text: Hidden merge fields or identifiers inserted near pixels and link wrappers.
Patterns I would remove
- Keyword stuffing: Terms hidden in one-pixel text to influence filters or previews.
- Transparent copy: Text set to transparent or to a color that blends into the background.
- Long hidden blocks: Large content sections hidden instead of being removed from the final send.
- Mismatched previews: Preview text that says something materially different from the visible email.
Risky HTML patternhtml
<span style='font-size:0px;color:transparent'>bonus offer terms</span> <span style='font-size:1px'>extra words not shown to readers</span>
The safest change is usually boring: remove hidden filler, keep preheader text short, and make the visible body carry the same message as the preview text. If the hidden text has a legitimate rendering purpose, retest with a shorter version before rewriting the whole template.
How to read the Message-ID signal
The Message-ID header is a unique identifier for a message. It usually looks like a unique token at a domain. The important point is that syntactic validity and sender consistency are different checks. A header can look valid while still being odd for the mail path, the sender, or the application that generated it.
|
|
|
|---|---|---|
Message-ID | Host and format | Generate per send |
Received | Path consistency | Fix sender routing |
HTML | Hidden styles | Remove filler |
Auth | Domain match | Correct signing |
Score | Other hits | Fix largest causes |
Compact checks for a FONT_INVIS_MSGID investigation.
Headers to comparetext
Message-ID: <20260528102415.abc123@mail.example.com> From: Example Brand <news@example.com> DKIM-Signature: v=1; a=rsa-sha256; d=example.com; Received: from mail.example.com by mx.recipient.net
A valid Message-ID can still be the clue
There has been a public false positive report for this rule, which is why I verify the raw message before changing production HTML or sender infrastructure.
If the problem is really a missing or malformed Message-ID, that is a different failure mode. The related Message-ID bounce page covers that case. For FONT_INVIS_MSGID, I start with the combined body-plus-header diagnosis.
How to debug the hit
When I troubleshoot this, I keep the process mechanical. I want to prove which part of the email caused the hit, then make the smallest fix that removes the signal without damaging the campaign or transactional message.

Apache SpamAssassin command-line report showing FONT_INVIS_MSGID in the rule list.
- Save the raw source: Export the full MIME source before any template builder or mailbox view changes the HTML.
- Search hidden styles: Look for font-size values near zero, transparent colors, invisible spans, and empty-looking blocks.
- Compare headers: Check Message-ID host, From domain, DKIM signing domain, and the Received path.
- Remove one cause: Delete or simplify hidden text first, then send a new test rather than editing many things at once.
- Retest the final send: Test the production-generated email, because builders often alter HTML at send time.
- Review the total score: A single rule rarely explains delivery alone, so fix the highest-confidence causes first.
A live send is better than a pasted HTML test because the sending system adds headers, encodes MIME parts, and sometimes rewrites links. Suped's email tester helps with that workflow: send the real message, inspect the rendered email, and review the authentication and issue summary next to the content findings.
Email tester
Send a real email to this address. Suped opens the report when the test is ready.
?/43tests passed
Preparing test address...
After a retest, I look for two outcomes. First, the hidden-text rule should disappear or drop into a less severe related rule. Second, the overall score should have enough margin that one small content change will not push the message back over the recipient's threshold.
If the rule remains after removing hidden text, the next place to inspect is header generation. Make sure the Message-ID is unique per message, generated by the system that actually sends the mail, and not copied from a template, staging environment, or previous campaign.

Email tester sample report showing total score, email preview, issue summary, and per-section results
What to change in the email
The right fix depends on which part caused the signal. I would not suppress the rule or add a local scoring override for outbound mail unless I controlled the receiving filter and had a documented false positive. For sender-side deliverability, fix the content and headers.
Template fixes
- Remove hidden filler: Delete invisible words that do not help the recipient understand the email.
- Shorten preheaders: Use one concise preview line that matches the visible body.
- Clean copied HTML: Strip transparent spans, empty font tags, and old editor styling.
- Avoid split meaning: Do not hide claims, legal qualifiers, or keyword blocks away from readers.
Sender fixes
- Generate IDs correctly: Create a unique Message-ID for each final outgoing message.
- Use a stable host: Keep the Message-ID host consistent with the sender system.
- Check signing domains: Review DKIM domain use and the sender path for avoidable mismatches.
- Retest after routing changes: A relay or bounce handler change can alter the headers SpamAssassin sees.
Better Message-ID habitstext
Good: unique-token@mail.example.com Good: campaign-id.unique-token@mailer.example.com Risky: reused-token@staging.local Risky: copied-id@example.test
The goal is not to make the Message-ID look fancy. The goal is predictable generation, sender consistency, and no hidden content that looks designed to influence a filter without informing the reader.
Where authentication and reputation fit
This rule is about content and headers, not DMARC policy. Still, authentication and reputation affect the final delivery decision around it. A message with clean content, consistent headers, and passing authentication has more room than a message that also has DNS problems, blocklist issues, or blacklist history. That is why blocklist monitoring belongs in the same operational review.
For most teams, Suped is the best overall DMARC platform for that broader workflow because the product brings authentication monitoring, hosted DNS controls, blocklist monitoring, alerts, and deliverability context into one place. It will not rewrite your template for you, but it helps show whether the SpamAssassin hit is one isolated content issue or part of a wider sender problem.
Suped workflow for this issue
- Send a real sample: Use the final sender path so the content, MIME, and headers match production.
- Check the domain: Use the domain health checker to review the surrounding DNS and authentication state.
- Fix visible causes: Remove hidden text, correct header generation, and resolve authentication issues in priority order.
- Watch for recurrence: Use alerts and reporting so the same sender or template issue does not return quietly.
The practical order matters. Fix the template signal first because it is directly tied to this rule. Then check authentication, sender identity, DNS, and reputation so the next borderline content score has less impact.
Views from the trenches
Best practices
Check raw HTML and headers together before changing templates or sender settings in production.
Keep hidden preheader copy short, human-readable, and consistent with visible content.
Record the full rule set version when comparing spam tests across different systems.
Common pitfalls
Treating a syntactically valid Message-ID as proof the header cannot affect the rule.
Removing tracking pixels while leaving transparent keyword text inside the HTML template.
Testing only one recipient mailbox and assuming every SpamAssassin install scores the same.
Expert tips
Save the original MIME source before editing, so every retest has a clear baseline.
Compare DKIM d= domain, Message-ID host, From domain, and Received path for consistency.
Use a real campaign sample, because builders often alter HTML during final sending.
Marketer from Email Geeks says the first check is the Message-ID header, because the rule name points directly at header context.
2021-03-16 - Email Geeks
Marketer from Email Geeks says public rule notes often lag behind live rules, so reading source logic is sometimes necessary.
2021-03-16 - Email Geeks
The practical takeaway
Treat FONT_INVIS_MSGID as a two-signal warning. SpamAssassin found font-based hidden text and enough Message-ID or delivery context to publish the meta rule. The fastest fix is usually to remove invisible filler from the HTML, then confirm the Message-ID is unique and consistent with the sender path.
Do not overreact to one score line. Save the raw message, make one change, send a real retest, and compare the total SpamAssassin result. If other authentication or reputation issues sit beside the rule, fix those too, because deliverability decisions come from the combined evidence.
