Groundmail

Blog

DMARC fail: what it means and how to fix it

DMARC fails when neither SPF nor DKIM passes for a domain that matches your From address. How to read the headers, find the failing sender and fix each cause.

By Groundmail5 min read

On this page

A DMARC fail means the receiving server could not confirm that the message really came from the domain in the From address. DMARC passes only when SPF or DKIM passes and the domain that passed matches (aligns with) your From domain. Most DMARC failures come from a service sending as your domain without signing DKIM with your domain, from email forwarding, or from a missing or broken DKIM record.

What DMARC checks

DMARC is defined in RFC 7489. For each message, the receiver asks two questions:

  1. Did DKIM pass, and does the signing domain (d=) align with the From domain?
  2. Did SPF pass, and does the envelope sender (return-path) domain align with the From domain?

If either answer is yes, DMARC passes. If both are no, DMARC fails, and the receiver applies the policy in your _dmarc record:

Policy What receivers do with failing mail
p=none Deliver as normal, send you reports
p=quarantine Usually deliver to spam
p=reject Refuse the message during the SMTP conversation

Alignment is the part people miss. With relaxed alignment (the default, adkim=r and aspf=r), the domains only need the same organizational domain, so mail.example.com aligns with example.com. With strict alignment (adkim=s or aspf=s) they must match exactly.

Pass versus aligned: an example

Here is a message from billing@example.com that fails DMARC even though SPF and DKIM pass:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@sender.example-esp.com header.s=k1;
       spf=pass smtp.mailfrom=bounce-123@sender.example-esp.com;
       dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=QUARANTINE) header.from=example.com
  • DKIM passed, but for sender.example-esp.com, not example.com.
  • SPF passed, but for sender.example-esp.com, not example.com.
  • Neither aligns with header.from=example.com, so dmarc=fail, and dis=QUARANTINE shows the receiver acted on the policy.

The same message passing DMARC would show header.i=@example.com (or a subdomain) on the DKIM line. To read these headers, open the message in Gmail, choose Show original, and paste the headers into the email header analyzer. The header format itself is defined in RFC 8601.

If the receiver rejects instead, the bounce tells you. Gmail's rejection reads:

550-5.7.26 Unauthenticated email from example.com is not accepted due to domain's DMARC policy.

Checklist for fixing a DMARC fail

  1. Confirm your DMARC record exists and parses with the DMARC checker.
  2. Find which sending source fails: one failing message's headers, or your DMARC aggregate reports for all of them.
  3. For that source, check whether DKIM signs with your domain. If not, set up custom DKIM in that service.
  4. Check whether SPF uses a return-path on your domain. If you can, set up a custom return-path (bounce) domain.
  5. Confirm your SPF record is valid and under 10 DNS lookups with the SPF checker.
  6. Re-test with a real send to the email spam test.
  7. Keep watching reports until every legitimate source passes, then tighten your policy.

Common causes and how to fix each

A third-party service sends as your domain without aligned DKIM

This is the most common cause. Your CRM, help desk, billing system or email provider sends mail From: you@example.com, but signs DKIM with its own domain and uses its own bounce address.

Fix: turn on custom or branded domain authentication in that service. It will give you DKIM records to publish, usually a TXT or CNAME at <selector>._domainkey.example.com. Once DKIM signs with d=example.com, DMARC passes regardless of SPF. If the service supports a custom return-path, set that too so SPF aligns as well.

If a service can't sign with your domain, send its mail from a subdomain you are willing to give it, or change the From address to the service's own domain.

DKIM is missing or broken

The DKIM line shows dkim=none (no signature) or dkim=fail (signature didn't verify). Common reasons:

  • The DKIM record was never published, or was published at the wrong host. Many DNS dashboards append your domain automatically, so entering s1._domainkey.example.com creates s1._domainkey.example.com.example.com.
  • A long key was split badly across TXT strings, or a character was lost when it was pasted.
  • Something changed the message after signing, such as a footer added by a gateway or mailing list.

Check the record with the DKIM checker, using the selector from the s= tag in the DKIM-Signature header.

SPF fails or doesn't align

SPF only checks the return-path domain, which most providers set to their own domain. So SPF alone rarely aligns unless you've set up a custom return-path. SPF can also fail outright:

  • Too many lookups. SPF allows 10 DNS lookups (RFC 7208, section 4.6.4). Past that the result is permerror. Remove includes for services you no longer use.
  • Two SPF records. A domain must publish exactly one v=spf1 record. Merge them:
example.com.  TXT  "v=spf1 include:_spf.google.com include:spf.groundmail.dev ~all"
  • A sender missing from the record. Add its include, but remember this only helps DMARC if the return-path is on your domain.

Forwarding and mailing lists

When a message is forwarded, the forwarding server sends it from its own IP, so SPF fails. If the forwarder doesn't change the message, DKIM still passes and DMARC passes with it. Mailing lists often change the subject or add a footer, which breaks DKIM too.

Fix: make sure every message is DKIM-signed with your domain, so plain forwarding doesn't break DMARC. Receivers such as Gmail also consider ARC (RFC 8617) headers added by forwarders. Failures from forwarding show up in reports as unfamiliar IPs where DKIM passes but SPF fails, and you usually can't fix them at the source. Don't add forwarders' IPs to your SPF record.

Spoofing

Sometimes the failing mail isn't yours. Reports show IPs you don't recognize sending as your domain, failing both SPF and DKIM. That is exactly what DMARC enforcement exists to stop. Once your own sources pass, move to p=quarantine and then p=reject.

Find failing sources with DMARC reports

One failing message tells you about one sender. To see all of them, add a reporting address to the rua= tag of your DMARC record. Receivers such as Gmail, Outlook and Yahoo then send a daily XML report listing every IP that sent mail as your domain and the SPF, DKIM and DMARC result for each.

_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

The raw XML is hard to read. Free DMARC monitoring reads the reports for you, groups the IPs by provider, flags unknown senders, and tells you when every legitimate source has passed for two weeks, which is when it's reasonable to move from p=none to p=quarantine. It works for any domain, including ones that don't send through Groundmail. If you don't have a DMARC record yet, the DMARC record generator builds one.

How Groundmail helps

When you add a domain to Groundmail, you publish a DKIM key and a return-path CNAME on your own domain, and we check both before the domain is verified. From then on every message is signed with d=yourdomain.com and bounces go to a return path on your domain, so both DKIM and SPF align and DMARC passes from the first send. DMARC monitoring is built into every domain in the dashboard; see the DMARC monitoring docs and domain setup docs. For the background on all three records, read our SPF, DKIM and DMARC guide.

Frequently asked questions

Can DMARC fail when SPF and DKIM both pass?

Yes. DMARC needs SPF or DKIM to pass for a domain that aligns with the From domain. If SPF passes for your provider's bounce domain and DKIM is signed with your provider's domain, both pass but neither aligns, so DMARC fails.

Does DMARC need both SPF and DKIM to align?

No. One aligned pass is enough. DKIM is the one to rely on, because it survives forwarding and SPF usually doesn't.

What happens to email that fails DMARC?

It depends on your policy. With p=none nothing changes and you only get reports. With p=quarantine receivers usually put failing mail in spam, and with p=reject they refuse it. Receivers can also apply their own judgment on top.

Should I switch to p=none to stop DMARC failures?

Switching to p=none stops receivers acting on the policy, but the mail still fails DMARC and is still more likely to be filtered. Fix the failing sender instead, and keep p=none only while you find all your sources.

How do I find which service is failing DMARC?

Read your DMARC aggregate reports. They list every IP that sent mail using your domain and whether SPF, DKIM and DMARC passed for each. A DMARC monitoring tool groups those IPs by provider so you can see which service needs fixing.

Send from infrastructure we own.

Groundmail runs its own mail servers on its own IP space. Start free on the shared transactional pool, then move to dedicated IPs or a dedicated server without changing your code.