← All articles
Email Errors

How to Fix SPF, DKIM or DMARC Failure Messages

By XYZREG Team · 2026-10-16 · Email Errors

Your emails are bouncing, landing in spam, or you're getting daily XML reports full of red "fail" entries. Somewhere in the chain of SPF, DKIM, and DMARC, something is broken — and the error messages are not exactly written for humans.

This guide is the troubleshooting companion to setup. You'll learn how to read a DMARC failure report, pinpoint whether the problem is SPF, DKIM, or alignment, and fix each cause step by step. If you haven't set up the three records yet, start with our step-by-step SPF, DKIM and DMARC setup guide first — this article assumes the records exist and something is failing.

The Quick Answer: Diagnose First, Fix Second

Every email authentication failure falls into one of three categories:

  1. SPF failure — the receiving server couldn't verify the sending IP against your SPF record. Common causes: too many DNS lookups, multiple SPF records, or a legitimate sender missing from the record.
  2. DKIM failure — the cryptographic signature didn't verify. Common causes: signing not enabled at the provider, a wrong or stale selector, or the message being altered in transit.
  3. DMARC failure despite SPF/DKIM "passing" — the checks passed for some other domain, not yours. This is an alignment problem, and it's the single most misunderstood failure type.

Resist the urge to start editing DNS records immediately. Read one failure report first — it will tell you exactly which category you're in, which saves you from "fixing" the wrong thing.

How to Read a DMARC Failure Report

When your DMARC record contains a rua=mailto:... tag, mailbox providers (Google, Microsoft, Yahoo, and others) email you a daily XML summary of every message that claimed to be from your domain. These aggregate (RUA) reports contain no message content — just statistics: sending IPs, message counts, and authentication results. They are the single best diagnostic tool you have.

The anatomy of a report

Open one report and you'll find three sections:

  1. policy_published — confirms the receiver actually saw your DMARC record and which policy it applied. If this doesn't match what you published, your record may be malformed or not yet propagated.
  2. record blocks — one per sending source. Each has:
  • row → source_ip, message count, and policy_evaluated (the DMARC verdict: pass or fail, plus the disposition applied)
  • identifiers → header_from (the domain the recipient saw in the From line)
  • auth_results → the raw SPF and DKIM check results
  1. Raw XML is fine for learning — but once you're getting dozens of reports a day, feed them into a free parser (several are listed in the sources below) rather than reading XML by hand.

The critical distinction: raw pass vs aligned pass

This is the insight that unlocks most "mystery" failures. In each record, compare two things:

  • auth_results/spf result — did SPF pass for whatever domain it checked?
  • policy_evaluated/spf — did SPF pass for your domain (aligned)?

These can disagree. A typical example: your marketing tool sends with a return-path of bounce.mailer.net. SPF checks bounce.mailer.net and passes — but DMARC evaluates SPF against your header_from domain, and that fails alignment. The report shows SPF "pass" in auth_results and SPF "fail" in policy_evaluated. Same story for DKIM: the signature can verify perfectly, but if the signing domain (d=) doesn't match your From domain, DMARC counts it as a fail.

Rule of thumb: if auth_results says pass but policy_evaluated says fail, you have an alignment problem, not a broken record. Skip to the DMARC alignment section.

Sort your sources into three buckets before touching anything

Go through the records and sort each sending source into one bucket:

  1. Yours and aligned — your IPs, your providers, DMARC passing. Leave alone.
  2. Yours but failing — a known service (your CRM, your newsletter tool, your website) with DMARC fails. This is your fix list. Work through it source by source.
  3. Unknown and failing — IPs you don't recognize sending at volume. That's impersonation — exactly what DMARC reporting exists to reveal. Don't "fix" these; they're the reason you keep enforcement on.

Fix bucket 2 before you tighten your policy. Never move to p=quarantine or p=reject while legitimate sources are still failing — you'll block your own mail.

SPF Failures: Causes and Fixes

Cause 1 — Too many DNS lookups: the 10-lookup limit (PermError)

This is the most common SPF failure in the wild. RFC 7208 caps SPF evaluation at 10 DNS lookups: every include, a, mx, redirect, and exists mechanism costs one lookup — including the lookups nested inside included records. ip4, ip6, and all cost nothing.

Exceed the limit and the receiver returns a PermError, which fails SPF for every message from your domain — even from perfectly authorized senders. One vendor's nested include can quietly push you over: Google Workspace alone consumes about 4 lookups, SendGrid around 5.

How to spot it: DMARC reports show SPF failing for all sources; an SPF checker tool reports "too many DNS lookups" or PermError.

Fixes, in order:

  1. Delete what you don't use. Old CRMs, retired marketing tools, duplicate includes — every stale include still spends a lookup. This is usually the fastest win.
  2. Replace mx and a with explicit ip4:/ip6: entries for your actual outbound IPs, if those addresses are stable. mx can fan out to many hosts and costs lookups that literal IPs don't.
  3. Flatten the record — replace include: mechanisms with the resolved IP ranges. This drops the lookup count near zero. The catch: vendors rotate their IP ranges, so a hand-flattened record goes stale and silently de-authorizes real mail. If you flatten manually, re-check quarterly; managed flattening services rescan automatically.
  4. Delegate heavy senders to subdomains — e.g. marketing.yourdomain.com for the newsletter tool. Each subdomain gets its own SPF record and its own 10-lookup budget. (Note: this requires relaxed SPF alignment, which is the default. It breaks under strict aspf=s.)

Aim for 6–8 lookups in steady state, not exactly 10 — the buffer absorbs it when a vendor adds nesting to their own include.

Cause 2 — More than one SPF record on the domain

A domain may publish only one SPF TXT record. Two records starting with v=spf1 on the same name produce a PermError per RFC 7208 — authentication breaks for every message, even if each record is individually valid. This usually happens when someone adds a second record instead of editing the existing one.

Fix: merge all mechanisms into a single v=spf1 ... string and delete the extras. Example: v=spf1 include:_spf.google.com -all plus v=spf1 include:sendgrid.net -all becomes v=spf1 include:_spf.google.com include:sendgrid.net -all.

Cause 3 — Syntax errors in the record

The record must start with v=spf1, use only recognized mechanisms, and end with exactly one all qualifier (~all softfail or -all hardfail — not both). Each quoted string in DNS must stay within 255 characters.

Fix: validate the record with an SPF checker tool after every edit. Common typos: missing v=spf1 prefix, two all mechanisms, or a provider's include copied with extra spaces.

Cause 4 — A legitimate sender is missing from the record

If one specific service's mail fails SPF while everything else passes, that sender simply isn't authorized. The usual suspects: a website contact form sending from the web server's IP, a new CRM nobody added, or a provider that sends with its own bounce domain (which SPF checks instead of yours).

Fix: add the sender — either its include: or its IP ranges, per the provider's documentation. Then re-check that you haven't blown the 10-lookup budget.

DKIM Failures: Causes and Fixes

Cause 1 — Signing isn't enabled at the provider

Publishing the DKIM DNS record is only half the job. In Microsoft 365 you must also enable signing in the admin center; in Google Workspace you generate the key and turn signing on. Many failures are simply "the DNS record exists but nothing is signing."

Fix: check the provider's admin console for a DKIM/signing toggle and confirm it's on for your domain.

Cause 2 — Wrong selector or stale key

The DKIM signature header references a selector (e.g. s1), and the receiver looks up <selector>._domainkey.yourdomain.com. If you rotated keys and the old DNS record is still published — or the selector in DNS doesn't match what the provider signs with — verification fails.

Fix: confirm the selector in your provider's console matches the TXT record in DNS. After rotating keys, keep the old record published for a few days (mail in transit may still reference it), then remove it.

Cause 3 — The message was modified in transit

DKIM signs the message body and selected headers. Mailing lists and some forwarders modify messages — adding footers, subject tags, or rewriting headers — which breaks the signature. This is normal behavior, not a misconfiguration, and it's why DMARC needs either SPF or DKIM aligned: forwarders typically preserve one even when they break the other.

Fix: don't chase this one at the DKIM level. Make sure SPF is aligned for those flows instead (or accept that list traffic authenticates differently). If the failures are only from mailing lists, that's expected.

DMARC Failures: When SPF and DKIM "Pass" but DMARC Still Fails

If your reports show raw SPF/DKIM passes but DMARC fails, you're looking at alignment — and this is the #1 cause of confusion in email authentication.

Alignment explained: strict vs relaxed

DMARC doesn't just ask "did SPF or DKIM pass?" It asks "did SPF or DKIM pass for the domain in the visible From header?" Two modes:

  • Relaxed (default): the authenticated domain must share the same organizational domain — so mail.yourdomain.com aligns with yourdomain.com.
  • Strict (adkim=s / aspf=s): the domains must match exactly.

The classic case: third-party sender with its own return-path

Your newsletter tool sends as you@yourdomain.com (the From header), but its return-path is bounce.mailer.net and its DKIM signature uses d=mailer.net. Both checks pass — for mailer.net, not for you. DMARC fails.

The three real fixes

  1. Custom return-path (for SPF alignment): most serious email providers let you configure a return-path on your own subdomain (e.g. bounce.yourdomain.com). SPF then authenticates your domain and aligns.
  2. DKIM signing on your domain (for DKIM alignment): publish the provider's DKIM keys under your domain so signatures carry d=yourdomain.com. This is the most robust fix and survives forwarding better than SPF.
  3. Subdomain delegation: send bulk/marketing mail from news.yourdomain.com with its own SPF/DKIM. Works under relaxed alignment (the default).

You only need one of SPF or DKIM aligned for DMARC to pass — fix whichever is easier for each sender.

The Step-by-Step Fix Workflow

Work through failures in this order:

  1. Collect one full day of reports before changing anything. You need the complete picture of your sending sources.
  2. Sort sources into the three buckets (aligned / yours-failing / unknown) as described above.
  3. Fix SPF structural errors first — multiple records, syntax, then the lookup count. These break everything at once.
  4. Fix per-sender SPF gaps — add missing legitimate senders to the record.
  5. Fix DKIM — enable signing, correct selectors, publish keys for third-party senders on your domain.
  6. Fix alignment — custom return-paths and DKIM-on-your-domain for third-party tools.
  7. Wait for DNS propagation (up to the old record's TTL; typically minutes to a few hours), then send test messages and check the next day's reports.
  8. Only then consider tightening DMARC from p=none toward quarantine and eventually reject.

Common Gotchas

DNS propagation delay — wait before retesting

After editing a record, the old version persists until its TTL expires. Retesting too early shows the same failure and sends you chasing a problem you've already fixed. Wait out the TTL (check what it was on the old record), then test.

Forwarding breaks SPF — and that's expected

When someone auto-forwards your mail (a common corporate setup), the forwarder's IP isn't in your SPF record, so SPF fails. DKIM usually survives forwarding, which is why having both mechanisms matters: DMARC passes if either one aligns. Don't try to "fix" SPF for forwarders — strengthen DKIM alignment instead.

Never jump to p=reject before the failures are fixed

Moving DMARC to p=reject while legitimate sources still fail is a self-inflicted outage: receivers will start dropping your real email. The safe rollout is p=none (monitor) → fix everything → p=quarantine → verify → p=reject. Each stage needs a few days of clean reports before advancing.

Frequently Asked Questions

Why does DMARC fail when SPF shows "pass" in my report?

Because of alignment. The SPF check passed for a different domain (like your sender's bounce domain), not the domain in your visible From header. DMARC requires an aligned pass. Compare auth_results (raw result) with policy_evaluated (aligned result) in the report — when they disagree, it's alignment, and the fix is a custom return-path or DKIM signed on your domain.

What does "SPF PermError: too many DNS lookups" mean?

Your SPF record requires more than 10 DNS lookups to evaluate (RFC 7208 limit), so receivers give up and fail SPF for all your mail. Fix it by removing unused includes, replacing mx/a with literal IPs, flattening includes to IP ranges, or moving heavy senders to subdomains. Aim for 6–8 lookups, not exactly 10.

Can I have two SPF records for different services?

No. A domain may publish exactly one SPF TXT record — two records cause a PermError that breaks authentication for every message. Merge all mechanisms into a single v=spf1 ... record.

My DKIM record is published but signatures still fail. Why?

The three usual suspects: (1) signing isn't actually enabled in your provider's admin console — publishing DNS is only half the job; (2) the selector in DNS doesn't match what the provider signs with, or you're looking at a stale key after rotation; (3) a mailing list or forwarder modified the message in transit. Check them in that order.

How long after fixing DNS should I wait before testing?

Wait out the TTL of the old record — typically minutes to a few hours, occasionally up to 48 hours for long TTLs. Then send test messages and check the next day's DMARC reports to confirm the fix landed. Retesting immediately against cached DNS will show the same old failure.

Should I just set DMARC to p=reject to stop the failures?

No — that's backwards. p=reject tells receivers to drop mail that fails DMARC, which includes your own legitimate mail if sources are still failing. Fix every legitimate source first (clean reports for several days), then move none → quarantine → reject in stages.

Sorting out email authentication? Once your SPF, DKIM, and DMARC failures are fixed and the daily reports go quiet, your business email lands in inboxes instead of spam — and your domain is protected from spoofing. If you're still setting things up, our step-by-step SPF, DKIM and DMARC setup guide walks through the initial configuration, and our complete domain registration guide covers managing your domain's DNS records.

Ready to get started with XYZREG?

Search Domains