
If SpamAssassin shows DKIM_SIGNED and DKIM_INVALID_DKIM, read that as: the message has a DKIM-Signature header, but SpamAssassin could not verify that signature. The small score beside the rule, such as 0.1, is only a SpamAssassin score contribution. It is not proof that the message landed in spam, and it is not proof that your whole domain has broken DKIM.
I start with the raw message headers, especially Authentication-Results. Then I compare the DKIM-Signature fields with DNS and the visible From domain. A domain can have a correct DKIM DNS record while one specific email still fails because the message changed after signing, the wrong selector was used, the public key lookup failed, or the signing domain does not match the domain needed for DMARC.
- Rule result: SpamAssassin rule names are clues about what its local engine observed.
- Score value: A low number means the rule has low weight in that SpamAssassin setup.
- Fix target: The fix is in the signature, message path, or selector DNS, not in the score.
- DMARC check: DKIM must pass and use a signing domain that matches the visible From domain.
Read the DKIM rules as clues, not verdicts
SpamAssassin is a scoring engine. A rule hit means one test matched. It does not mean the message failed every mailbox provider's filtering, and it does not mean the rule is wrong. It means that SpamAssassin's DKIM plugin and local rule set produced that result for that exact copy of the message.
The public rule descriptions are often short because many rules are simple pattern checks, meta rules, plugin outputs, or local custom rules. If you run your own SpamAssassin installation, the installed rules usually give more useful detail than any public list.
The short version
Treat SpamAssassin DKIM results as diagnostic output. The important question is not whether a rule fired. The important question is whether DKIM passed in the receiving system's trusted Authentication-Results header and whether that pass can satisfy DMARC.
- Header present: The message has a DKIM-Signature header.
- Signature failed: The header exists, but cryptographic verification did not pass.
- Score context: The points are local SpamAssassin weighting, not a universal inbox placement score.
- Next evidence: Use full headers and DNS, not screenshots of a partial score table.
|
|
|
|---|---|---|
DKIM_SIGNED | Signature header present | Validate it |
DKIM_VALID | DKIM passed | Check DMARC match |
DKIM_VALID_AU | Author domain passed | Good signal |
DKIM_INVALID | Signature failed | Inspect headers |
DKIM_INVALID_DKIM | DKIM signature invalid | Check hash and key |
Common SpamAssassin DKIM rules and the practical next step.
Typical SpamAssassin DKIM outputtext
0.1 DKIM_SIGNED Message has a DKIM or DK signature 0.1 DKIM_INVALID_DKIM DKIM or DK signature exists, but is not valid
Why a valid-looking domain can still fail DKIM
The most common misunderstanding is treating a correct DNS record as proof that every outgoing message is correctly signed. DNS proves the public key is available. It does not prove that a specific message body, header set, selector, and signing domain all match the signature placed on that message.
DNS record is correct
This proves the public key side of DKIM.
- Key: The selector record resolves in DNS.
- Format: The TXT record parses as DKIM.
- Limit: It says nothing about later message changes.
- Risk: A different selector can still fail.
Message signature is valid
This proves the signed message survived verification.
- Hash: The body hash matches the body.
- Headers: Signed headers still match.
- Domain: The signing domain is the expected one.
- Path: Nothing changed after signing.
A different envelope domain is not, by itself, a DKIM failure. DKIM validates the DKIM-Signature header and the d= signing domain. The envelope sender matters for SPF and for DMARC's SPF path. For DKIM-based DMARC pass, the signing domain must match the visible From domain at the organizational-domain level.

DKIM verification checks the signature header, signed headers, body hash, and DNS key.
Start with Authentication-Results
The best next move after a SpamAssassin DKIM hit is to inspect the full raw email. I care most about Authentication-Results because it records what a receiver actually checked. Use the header added by the system that accepted the message, not a copied or user-supplied header lower in the message.
Authentication-Results exampletext
Authentication-Results: mx.example.net; dkim=fail reason="signature verification failed" header.d=example.com; spf=pass smtp.mailfrom=bounces.sender.example; dmarc=fail header.from=example.com
This header tells you whether the DKIM failure is real at the receiver and whether DMARC had another path to pass. If the Authentication-Results header says dkim=pass, but SpamAssassin says invalid, trust the receiver's header first and then check how SpamAssassin was run.
- dkim=pass: The receiver verified at least one DKIM signature.
- dkim=fail: Read the reason field, then test the selector and signed content.
- header.d: Compare this signing domain with the visible From domain.
- header.s: Use this selector when you query the public DKIM key.
Header trust matters
A message can contain several Authentication-Results headers. Trust the one added by your receiving system or a mailbox provider you control. Treat older ones as useful history, not final evidence.

Apache SpamAssassin terminal output showing DKIM_SIGNED and DKIM_INVALID_DKIM rule hits.
Check the DKIM signature fields
Once the headers confirm a DKIM failure, inspect the DKIM-Signature header. This header tells you the signing domain, selector, canonicalization mode, signed headers, body hash, and signature value. Those fields point directly at the failure area.
DKIM-Signature header exampletext
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=selector1; t=1710000000; h=from:to:subject:date:message-id; bh=abc123base64=; b=def456base64=
- d=: Signing domain. It must match the From domain for DKIM to satisfy DMARC.
- s=: Selector. Query this value at selector._domainkey under the signing domain.
- c=: Canonicalization. relaxed/relaxed handles normal whitespace changes.
- h=: Signed headers. A change to one of these headers can break verification.
- bh=: Body hash. This fails when the body changes after signing.
- b=: Signature data. It fails when signed headers or the body hash fail.
Selector DNS exampledns
selector1._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."
For a quick DNS-level validation, run the selector through the DKIM checker. That confirms whether the public key is published and parseable before you spend time on message-body changes.
DKIM checker
Check selector records and public key configuration.
?/7tests passed
A clean selector lookup narrows the problem. At that point, focus on the actual message path: where it was signed, what system touched it afterward, and whether the final received copy matches what the signer originally signed.
Troubleshoot in the right order
DKIM troubleshooting gets messy when you jump straight to DNS edits. Work through the evidence in order. The aim is to isolate whether the failure is lookup, key, header, body, or domain-match related.

A DKIM troubleshooting flow: raw email, SpamAssassin rule, authentication results, DKIM fields, DNS selector, root cause.
- Preserve raw email: Use the full message source, including untouched headers and body.
- Read receiver results: Find the trusted Authentication-Results header and DKIM reason.
- Map signer fields: Record the signing domain, selector, signed headers, and body hash.
- Check selector DNS: Confirm the TXT record exists, has one key, and matches the signer.
- Inspect modifications: Look for footers, tracking rewrites, gateway edits, or list changes.
- Retest one path: Send a simple message through the same sender and compare results.
If your end symptom is landing in spam despite authentication passing, treat DKIM as only one part of the investigation. Content, complaint rate, sending patterns, and domain reputation still matter.
The most common DKIM failure causes
When SpamAssassin says the DKIM signature exists but is invalid, the cause is usually one of a small number of practical issues. The table below keeps the language compact because the fix is usually found by matching a failure symptom to the message path.
|
|
|
|---|---|---|
Body hash | Content changed | Sign last |
No key | Selector DNS | Publish TXT |
Wrong key | Signer config | Rotate selector |
Header change | Subject or From | Stop rewrite |
DNS format | TXT splitting | Fix record |
Duplicate signer | Mail path | Keep required |
Common DKIM failure causes and where to inspect first.
A body hash failure usually means the message body was changed after signing. If that is your exact header result, use the body hash verification troubleshooting path before editing DNS. Footer insertion, MIME rewriting, and link decoration after DKIM signing are common causes.
If the result mentions no public key, the selector lookup is the first place to fix. The no key errors pattern usually means the selector in the header does not resolve at the signing domain, or the DNS provider has the record under the wrong host name.
Do not fix the wrong layer
If a single test message fails DKIM, changing the domain's DKIM record without checking the actual selector and message path can break mail that was already passing. Prove the failure layer first.
How DMARC changes the interpretation
DKIM passing is not the same as DMARC passing. DMARC looks at the visible From domain. DKIM can satisfy DMARC only when the DKIM signing domain matches that From domain at the organizational-domain level. SPF can satisfy DMARC through the envelope sender only when its authenticated domain also matches the visible From domain.
DKIM passes but DMARC fails
- Domain: The signing domain differs from the visible From domain.
- Envelope: SPF passed for a return-path domain that does not match From.
- Policy: The receiver applies the visible From domain's DMARC policy.
- Fix: Sign with the From domain or a valid organizational match.
DKIM fails but DMARC passes
- SPF: SPF passed using a domain that matches the visible From domain.
- Forwarding: DKIM broke in transit, but SPF still satisfied DMARC.
- Risk: Forwarded mail often loses SPF, so DKIM still needs a fix.
- Fix: Repair DKIM instead of relying on SPF as the only path.
This is where DMARC monitoring matters. A one-off SpamAssassin result tells you about one message. Aggregate DMARC reports show which sources are passing, failing, and using the wrong domain over time.

DMARC record detail view showing SPF, DKIM, DMARC, rDNS diagnostics, and DNS records
In Suped's product, this workflow is practical because the platform groups DKIM, SPF, DMARC, rDNS, and DNS record diagnostics in one place. You can move between an invalid DKIM symptom, the source sending the mail, and the exact DNS records that need review.
For a broader record check before you dig into a specific message, the domain health checker can confirm whether DMARC, SPF, and DKIM records are published in a usable shape.
When SpamAssassin documentation is not enough
There is no single complete public explanation for every SpamAssassin test you will see. Public lists explain many standard rules, but local installations often add custom rules, change scores, or run plugins in a different configuration. Some results are set by plugin code rather than a plain rule file.
Finding local SpamAssassin rule definitionsbash
grep -R "DKIM_INVALID_DKIM" /usr/share/spamassassin grep -R "DKIM_SIGNED" /usr/share/spamassassin spamassassin -D < message.eml
- Local rules: Search the installed rule files when the public description is too short.
- Meta rules: Some rules fire only after other tests combine into a higher-level signal.
- Plugin code: DKIM checks can come from Perl plugin behavior instead of a simple regex.
- Score changes: The same rule name can carry a different score in another installation.
Use the score carefully
A public SpamAssassin score website can be useful for fast testing, but it is not the same thing as a real receiver decision. Use it to find obvious authentication issues, then confirm with headers and aggregate reporting.
What to fix first
The priority depends on what the headers show. I ignore tiny score changes when the trusted receiver says DKIM passed. I fix immediately when a production source has DKIM failures that also cause DMARC failures.
DKIM troubleshooting priority
Treat SpamAssassin points as low priority unless trusted headers show a real authentication failure.
Informational
Low
Rule hit only
Investigate
Medium
Trusted header says DKIM failed
Fix now
High
DKIM failure also breaks DMARC
Monitor
Ongoing
DKIM passes, but source patterns changed
Suped is the best overall practical DMARC platform for most teams when this needs to be managed beyond a single test message. Suped's product turns authentication failures into source-level issues, fix steps, alerts, and reporting that people can act on without reading raw headers every day.
Suped workflow
- Detect: Find verified and unverified sources causing DKIM or DMARC failures.
- Explain: Show the issue, affected source, and practical steps to fix.
- Protect: Use hosted DMARC, hosted SPF, SPF flattening, and hosted MTA-STS.
- Scale: Manage many domains with MSP dashboards and blocklist (blacklist) monitoring.
Views from the trenches
Best practices
Use full raw headers before changing DNS, because partial score screenshots hide context.
Compare SpamAssassin output with trusted Authentication-Results before deciding.
Check the selector and signing domain together, because one without the other misleads.
Retest with a simple message path after each fix so new edits do not hide the cause.
Common pitfalls
Treating DKIM_SIGNED as a pass causes teams to miss invalid signatures in headers.
Assuming a correct DNS key proves every message is signed correctly wastes time.
Blaming a different envelope domain for DKIM failure confuses SPF with DKIM checks.
Using a public score as a deliverability verdict overstates what SpamAssassin proves.
Expert tips
Search installed SpamAssassin rules when public descriptions are too short to act on.
Use debug output only after headers and DNS confirm the failure layer is unclear.
Fix post-signing body edits before rotating keys when the body hash is failing now.
Track aggregate DMARC reports so one-off DKIM failures become source-level issues.
Marketer from Email Geeks says public SpamAssassin rule documentation is incomplete, so installed rules and plugin behavior often explain more than the public list.
2024-07-19 - Email Geeks
Marketer from Email Geeks says DKIM_SIGNED only confirms that a DKIM-Signature header exists, while DKIM_INVALID_DKIM means that signature did not verify.
2024-07-19 - Email Geeks
A practical reading of the score
The direct interpretation is simple: DKIM_SIGNED means the message carries a DKIM signature, and DKIM_INVALID_DKIM means SpamAssassin could not validate it. The score beside those rules is the local weight of the rule, not a universal deliverability grade.
The fix depends on the header evidence. If the receiver says DKIM passed, do not chase the SpamAssassin score first. If the receiver says DKIM failed, check selector DNS, body hash changes, signed header changes, and the signing domain's match with the visible From domain. After that, use DMARC reporting so repeated failures are tied to sources instead of isolated test messages.

