DKIM fail is not a cosmetic warning. It means a receiving server checked your signature, compared it to the message it actually received, and decided the message can’t be trusted. That kills inbox placement fast. If you’re still tightening the rest of your mail stack, start with our guide to business email so SPF, DKIM, DMARC, routing, and mailbox setup all line up.
You send the message. It looks normal on your side. Then Gmail, Microsoft, or Yahoo sees dkim=fail, and now you’re dealing with spam placement, soft blocks, or outright rejection. Open rates crater. Support tickets start. Nobody on the team knows whether the problem lives in DNS, your sender, or some security appliance rewriting mail in transit.
Here’s the fix: treat DKIM like incident response, not guesswork. Read the auth result. Identify the failure class. Check the selector. Check the key. Check what touched the message after signing. Then fix the exact break point.
What does dkim fail actually mean?
DKIM fail means the receiving server could not validate the cryptographic signature attached to your message. The cause is usually one of four things: the body changed after signing, the public key in DNS is missing, the key in DNS does not match the private key used to sign, or DNS lookup failed.
DKIM has two moving parts defined in RFC 6376: the body hash in bh= and the header signature in b=. If either one breaks, you get dkim fail. That does not always mean spoofing. It often means your own infrastructure is signing mail too early, publishing the wrong key, or letting another hop modify the message on the way out.
Think of DKIM like a tamper seal on a package. If the box arrives with extra tape, a swapped label, or the wrong seal code, the receiver assumes the package is no longer trustworthy.
The first place to look is the Authentication-Results header in the failed message. That tells you what failed and usually points straight at the category of problem.
Authentication-Results: mx.google.com;
dkim=fail (body hash did not verify) header.i=@example.com header.s=tm1;
spf=pass smtp.mailfrom=example.com;
dmarc=fail header.from=example.comIf you need to confirm your domain records before touching the sender, compare what you published against TrekMail’s required DNS records.
The four DKIM fail modes you’ll actually see
Most DKIM incidents fall into four buckets: body hash mismatch, selector or key mismatch, malformed or truncated DNS key, and forwarding or relay modification. If you classify the failure correctly first, the fix is usually quick. If you don’t, you’ll waste hours rotating keys that were never the problem.
| Authentication result | What it usually means | Where to look first |
|---|---|---|
dkim=fail (body hash did not verify) | Message body changed after signing | Outbound relays, disclaimers, link rewriting, canonicalization |
dkim=fail (signature did not verify) | Private key and DNS public key do not match | Selector record, recent key rotation, wrong sending platform |
dkim=permerror (no key for signature) | Receiver could not find the public key | Selector hostname, DNS propagation, record format |
dkim=temperror | Temporary DNS lookup or resolver problem | Authoritative DNS health, TTL, nameserver availability |
That table is the fast triage view. Now you need to prove which one you have.
Failure mode 1: body hash mismatch
A body-hash DKIM fail means the DNS record is probably fine, but the message body that arrived is not byte-for-byte equivalent to the body that was signed. This is the most common DKIM break in production mail flows.
RFC 6376 is clear on the verifier behavior: if the recalculated body hash does not match the bh= value, the verifier returns permanent failure. In plain English, something touched the message after signing.
Common causes:
- Microsoft 365, Exchange, or security gateways append legal disclaimers after the message is signed.
- Mimecast, Barracuda, Proofpoint, and similar filters rewrite links for inspection.
- A relay normalizes whitespace or line endings in a way your signer did not tolerate.
- An app signs first, then a downstream gateway modifies MIME boundaries or adds banners like
[External].
Check the c= value in the signature. If you see c=simple/simple, you are running a stricter mode than most operators want. The relaxed body canonicalization in RFC 6376 ignores trailing whitespace and collapses repeated whitespace inside lines, which helps with harmless changes that would otherwise cause dkim fail.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=tm1; h=from:to:subject:date:mime-version;
bh=...; b=...The bigger fix is architectural: sign at the edge, after every footer, rewrite, routing rule, or compliance stamp has already happened. If signing happens in the middle of your path, dkim fail is just a matter of time.
If you’re forwarding mail in ways that already stress authentication, read email forwarding and forward domain email to Gmail. Forwarding is where “it worked in testing” turns into “why is DMARC failing in production?”
Failure mode 2: selector or key mismatch
This DKIM fail happens when the message says it was signed with selector X, but DNS either has no record for selector X or has a public key that does not match the private key that signed the message. That is a configuration error, not a content problem.
Start with the signature header. Find the selector and domain:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=k1; ...Then query that exact selector:
dig txt k1._domainkey.example.com +shortIf you get nothing back, the record is missing, published under the wrong host, or not propagated yet. If you do get a record back, compare it to the key the current sender expects. This is where migrations and mixed sending stacks break hard. A lot of teams rotate keys in one platform and forget that another platform is still signing with the old private key.
This shows up often when you use multiple senders for the same domain: app mail through SES, support mail through Microsoft 365, campaigns through another ESP. One sender rotates, another sender still signs, DNS changes once, and now dkim fail starts intermittently.
If you’re on TrekMail’s managed sending path, use Managed TrekMail SMTP so signing happens on the final outbound hop. If you’re on the Nano plan or using your own sender, check custom SMTP (BYO) because TrekMail is the client in that setup, not the signer.
Failure mode 3: the long-key DNS trap
This DKIM fail happens when your public key is published incorrectly in DNS, usually because a 2048-bit key was pasted into a provider UI that mishandled the TXT value. The result is often permerror, bad format, or a selector lookup that returns a chopped key.
RFC 8301 says signers must use at least 1024-bit RSA keys and should use at least 2048-bit keys. That is the right direction. The catch is operational: long TXT values hit real DNS UI limits.
If your provider does not handle long TXT strings well, the record may be truncated or quoted incorrectly. That creates dkim fail even when the private key on the sender is correct.
; Good DKIM TXT record pattern
k1._domainkey.example.com IN TXT (
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQE..."
"restOfThePublicKeyContinuesHere..."
)Run a live lookup and inspect the full response, not just the first fragment:
dig txt k1._domainkey.example.com +shortIf you recently changed DNS providers, moved zones, or copied records by hand, this is one of the first places to check. It’s boring. It breaks constantly.
Failure mode 4: forwarding, relays, and alignment gaps
Forwarding creates DKIM fail when an intermediate system changes the message while SPF is already broken by design. That combination is what turns a harmless relay into a DMARC failure and, sometimes, a rejection.
Here’s the normal forwarding problem. You send mail from example.com to a user at a university. That university forwards to Gmail. SPF can fail because the forwarding server is not your original sender. DKIM is supposed to survive that. But if the forwarder adds a footer, rewrites a link, or prepends a subject tag, now DKIM breaks too. Then DMARC fails.
Google’s current sender guidance says direct mail to personal Gmail accounts must have SPF and DKIM set up, and alignment must exist with at least one of them. Google also notes that forwarded and mailing-list traffic is different and should carry ARC when possible. That matters because dkim fail in a forwarding path is often not a sign your base setup is wrong. It is a sign the forwarder modified the message.
If forwarding is part of your workflow, this is also where SRS and sane routing policy matter. TrekMail supports SRS forwarding, which helps keep forwarded mail from collapsing under SPF. That does not replace DKIM. It reduces collateral damage around it.
For alias-heavy setups, also read email alias forwarding and create email with your domain. A lot of “mystery dkim fail” reports are really forwarding design mistakes hiding behind alias sprawl.
Exact places to look when dkim fail shows up
If you need a repeatable process, check the auth header, then the selector lookup, then the signing path, then alignment. That order eliminates the fastest root causes first and stops you from changing DNS when the real issue is mail modification after signing.
- Open the raw message and find
Authentication-Results. Write down the exact DKIM verdict. - Find the
d=,s=, andc=tags in theDKIM-Signatureheader. - Query the selector in DNS with
dig. Confirm the hostname isselector._domainkey.example.com. - Verify the sending platform is the one you think is signing. Mixed platforms cause intermittent dkim fail.
- Check whether a gateway, filter, or forwarder modifies the body or signed headers after signing.
- Confirm alignment: the
d=domain must align with the visibleFrom:domain for DMARC to pass on DKIM.
One more trap: if you are testing by pasting fragments into a third-party checker instead of using the full original message source, you can generate false body-hash errors. Always inspect the raw message or an exported .eml when you’re chasing dkim fail.
Old way vs new way: fixing dkim fail with TrekMail
The old way is patching DNS, relays, and footers across three vendors while trying to guess which system signed first. The new way is simpler: put the signer at the final outbound edge, keep DNS clean, and separate managed sending from bring-your-own sending on purpose.
| Old way | New way |
|---|---|
| Multiple internal hops modify the message after signing | Final outbound gateway signs the exact message that leaves |
| Manual key rotation across several tools | Managed SMTP handles signing and key lifecycle on paid plans |
| Free-form DNS edits with duplicate SPF or broken DKIM hosts | Use one clean DNS template and verify each record |
| Forwarding designed without SRS or ARC awareness | Use standards-first forwarding and preserve authentication where possible |
With TrekMail, the split is straightforward. The Nano plan is always free and uses BYO SMTP. Paid plans start at $3.50 per month and add managed SMTP. If you want TrekMail to own the last signing hop, use a paid plan. If you want your own SES, SendGrid, or Mailgun setup to sign mail, keep TrekMail as the control plane and debug DKIM in your external sender. Paid plans include a 14-day free trial, and that trial requires a credit card. If you want the plan breakdown, use TrekMail pricing.
That division matters because dkim fail on BYO SMTP is rarely a TrekMail mailbox issue. It is usually a sender-side selector, key, or post-signing modification issue.
Final checklist for any dkim fail incident
DKIM fail is fixed fastest when you stop treating it like a vague deliverability problem and start treating it like a specific verification error. Read the result, test the selector, inspect the signing path, and only then change configuration.
Use this quick checklist before you touch production:
- Read the full auth header. Don’t guess from a bounce summary.
- Confirm whether dkim fail is body hash, signature verification, permerror, or temperror.
- Look up the exact selector in DNS.
- Make sure the published key is complete and correctly quoted.
- Move signing to the final outbound edge if anything changes the message downstream.
- Use
c=relaxed/relaxedunless you have a hard reason not to. - Check DMARC alignment between
d=and the visibleFrom:domain.
If you keep seeing dkim fail, the answer is almost never “wait and hope.” Something is broken. Fix the signer placement, fix the selector, or fix the relay that keeps touching the message after it was sealed.