Issue Description
This concerns the default rule set distributed via spamFilterRulesUrl
(spam-filter-rules.json.gz), not the server code.
MID_RHS_MATCH_FROM is scored +1.00. The tag fires when the Message-ID
host matches the From domain — conventional, correct sender behaviour,
not a spam indicator. The result is a flat one-point penalty applied to
well-configured senders.
The same loop that produces it also produces MID_RHS_MATCH_ENV_FROM, for
the envelope-from identity. That tag has no score entry at all, i.e. 0.00.
Two tags expressing the same property against two identities, only one
of which is penalised — which is what makes me think the +1.00 is
unintended rather than a deliberate heuristic.
Expected Behavior
A Message-ID whose right-hand side matches the From domain should be
scored neutrally, or negatively if the original intent was to reward the
match. It should not push a message toward the spam threshold.
Actual Behavior
MID_RHS_MATCH_FROM contributes +1.00 to the final score.
Two legitimate messages received on a production server, default
threshold 5.0, both classified as spam, both carrying the tag:
- Microsoft 365 tenant, spf=pass aligned, dkim=pass — score 7.10
- Government service notification, spf=pass aligned,
dkim=pass aligned — score 5.80
In the second case, removing this tag alone yields 4.80, i.e. below
threshold: it is the difference between inbox and junk. In both, the
Message-ID domain matched the From domain exactly.
Reproduction Steps
- Run with the default rule set (no local SpamTag overrides).
- Receive any message whose Message-ID host equals the From domain —
which is what most correctly configured senders produce. - Inspect X-Spam-Result on the delivered message: it lists
MID_RHS_MATCH_FROM (1.00). - Compare with MID_RHS_MATCH_ENV_FROM, which appears at (0.00).
Relevant Log Output
sample 1 — Microsoft 365 tenant
X-Spam-Result: DKIM_ALLOW (-0.20), SPF_ALLOW (-0.20),
MID_RHS_MATCH_ENV_FROM (0.00),
DMARC_NA (1.00), HELO_IPREV_MISMATCH (1.00),
MID_RHS_MATCH_FROM (1.00), MIME_BASE64_TEXT_BOGUS (1.00),
PYZOR (3.50)
X-Spam-Score: spam, score=7.10
sample 2 — government service notification
X-Spam-Result: DKIM_ALLOW (-0.20), SPF_ALLOW (-0.20),
MID_RHS_MATCH_ENV_FROM (0.00),
MIME_HTML_ONLY (0.20), DMARC_NA (1.00),
MID_RHS_MATCH_FROM (1.00), PHISHING (4.00)
X-Spam-Score: spam, score=5.80
Stalwart Version
v0.16.x
Installation Method
Binary (Linux)
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
Additional Context
The tag is emitted at crates/spam-filter/src/analysis/messageid.rs:62-76
(v0.16.20):
for (part, sender) in [
("FROM", &ctx.output.from.email),
("ENV_FROM", &ctx.output.env_from_addr),
] {
if !sender.address.is_empty() {
if mid.contains(sender.address.as_str()) {
ctx.result.add_tag(format!("MID_CONTAINS_{part}"));
} else if mid_host.fqdn == sender.domain_part.fqdn {
ctx.result.add_tag(format!("MID_RHS_MATCH_{part}"));
} else if /* SLD match */ {
ctx.result.add_tag(format!("MID_RHS_MATCH_{part}TLD"));
}
}
}
Scores in the current rule set:
MID_RHS_MATCH_FROM 1.0
MID_RHS_MATCH_ENV_FROM no entry (0.0)
Suggested fix: score MID_RHS_MATCH_FROM at 0.0, or negative if rewarding
the match was the intent. If the +1.00 is deliberate, documenting the
reasoning and scoring MID_RHS_MATCH_ENV_FROM consistently would help.
Happy to provide full headers for both samples.
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on