Join our Newsletter — 33% off our NHI Course
Home› Guides› DMARC, SPF and DKIM Failure Troubleshooting Guide: Diagnosing…
Guide Email & Communications Security

DMARC, SPF and DKIM Failure Troubleshooting Guide: Diagnosing Authentication Results, Errors and Alignment Failures

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 11 November 2026 16 min read
On this page

When legitimate mail starts bouncing or landing in spam with a DMARC failure, the cause is almost never DMARC itself: it is an SPF or DKIM result that did not pass, or a pass that did not align with the From domain. This guide is a diagnostic reference for that moment. It works from the symptom (a bounce code, an Authentication-Results header, a line in an aggregate report) to the likely causes in order of frequency, shows where to look for each one, and gives the fix and how to stop it coming back. It is for email administrators, platform engineers and security teams who own a sending domain. Concepts, record design and the rollout to p=reject are covered in the DMARC, SPF and DKIM Guide, which this page does not repeat. Result names, error strings and limits were checked against the RFCs and Google and Microsoft documentation on 11 November 2026.

Key takeaways

  • Read the receiver's verdict before touching DNS. The Authentication-Results header (or Microsoft's compauth reason code) tells you which mechanism failed and which domain it evaluated. Most wasted effort comes from editing the SPF record when DKIM, or alignment, was the problem.
  • A pass is not enough, it must align. Under RFC 9989, DMARC passes only when SPF (on the MAIL FROM domain) or DKIM (on the d= domain) passes and that domain matches the From domain, relaxed or strict. A supplier passing SPF on its own bounce domain still fails DMARC for you.
  • SPF permerror is self-inflicted. More than 10 DNS-querying terms, more than two void lookups, or two SPF records all produce permerror under RFC 7208, which most receivers treat as a failure.
  • DKIM body hash failures mean something changed the message. Footers, disclaimers, mailing lists and security gateways rewrite content after signing. Find the hop that changed it rather than weakening the signature.
  • Forwarding breaks SPF by design. Plan for DKIM to carry DMARC through forwarders and lists, and treat ARC as a receiver's discretion, not a fix you control.

Step one: read the verdict the receiver gave

Every diagnosis starts from evidence the receiving system produced, not from a DNS lookup on your side. Get a full copy of an affected message with headers (from a test mailbox at the affected provider or from the recipient) or the bounce (non-delivery report) text, and read three things.

  1. The Authentication-Results header. RFC 8601 defines it. Read spf= with smtp.mailfrom (the domain SPF was checked against), dkim= with header.d and header.s (signing domain and selector, one result per signature), and dmarc= with header.from. If SPF passed for bounces.supplier.example and DKIM passed for supplier.example while the From domain is yourdomain.example, both mechanisms worked and alignment is the fault.
  2. Which hop wrote it. Only trust the Authentication-Results header added by the final receiver (its authserv-id names it). Headers inherited from earlier hops can be stale or forged.
  3. The bounce code. Microsoft consumer services (Outlook.com, Hotmail) return 550 5.7.515 Access denied, sending domain <domain> does not meet the required authentication level. to senders of 5,000 or more messages that fail its SPF, DKIM and aligned DMARC requirements. Google says unauthenticated messages to Gmail might be rejected with error 5.7.26. A DMARC rejection from any receiver usually names DMARC or the sender's policy in the text.

Result values and what they mean

MechanismResultMeaning (RFC 7208 / RFC 8601)First place to look
SPFfailExplicit statement the client is not authorised (-all matched)Sending IP missing from the record of the MAIL FROM domain
SPFsoftfailWeak statement the host is probably not authorised (~all)Same as fail; the receiver weighs it less strongly
SPFneutral / noneOwner asserts nothing (?all) / no SPF record retrievedWrong MAIL FROM domain, or record missing on that domain
SPFpermerrorPublished records could not be correctly interpretedLookup count, void lookups, duplicate records, syntax
SPFtemperrorTransient, generally DNS, error during the checkAuthoritative DNS reachability and response times
DKIMfailAn acceptable signature failed verificationBody or header changed after signing, or wrong key published
DKIMneutralSignature had syntax errors or could not be processedMalformed DKIM-Signature header from the signer
DKIMpolicySigned, but signature not acceptable to local policyKey length or algorithm below the receiver's minimum
DKIMpermerror / temperrorUnrecoverable / likely transient verification errorKey record missing or malformed / DNS timeout on the selector
DKIMnoneMessage was not signedSigning not enabled on this sending path
DMARCfailNo aligned SPF or DKIM passCompare smtp.mailfrom and header.d with header.from

Microsoft 365 composite authentication codes

Microsoft adds compauth= with a reason code to the Authentication-Results header. The ones that matter most when diagnosing, as documented on Microsoft Learn:

ReasonDocumented meaningWhat to do
000Explicit DMARC fail with p=quarantine or p=rejectFix alignment for this sending source (sections below)
001Implicit fail: no records, or weak policy (~all, ?all, p=none)Publish SPF, DKIM and DMARC; Microsoft is judging without your policy
010DMARC fail with enforcement, sender is one of your own accepted domainsInternal app or relay sending as your domain unauthenticated
108DKIM failed due to body modification by earlier legitimate hopsLocate the gateway or list that rewrites content
112DNS timeout prevented the DMARC record being retrievedCheck authoritative DNS health for _dmarc
130ARC result from a trusted ARC sealer overrode the DMARC failureExpected for configured forwarders; confirms the underlying fail
905DMARC not enforced due to complex routingInbound path via on-premises or third-party gateway; fix the connector design

The same header carries dmarc=permerror when Microsoft found a malformed DMARC record and dmarc=temperror for a temporary lookup error.

SPF failures: diagnosis and fix

SPF is evaluated against the envelope sender (MAIL FROM, also called Return-Path), not the visible From. The first question is always which domain the receiver checked, from smtp.mailfrom.

SPF fail or softfail

  • Most common cause, a new or changed sending source: a SaaS platform, a new region of an email API, or an on-premises relay sends using your MAIL FROM domain from IPs not in your record. Look up the record with dig +short TXT yourdomain.example, then compare the connecting IP from the first Received header added by the receiver. Fix by adding the provider's documented include or IP range, after confirming the source is legitimate in the Email Sending Sources Inventory Template.
  • Next most common, forwarding: the message passed at the first hop and failed when an alias, forwarding rule or list re-sent it from its own IP with your MAIL FROM unchanged. This cannot be fixed in your SPF record. Make sure DKIM signs with your domain so DMARC survives.
  • Less common, IPv6 or a secondary egress: a sender that falls back to IPv6 or a disaster recovery relay uses an address only covered by ip4 entries.

SPF permerror

Cause (RFC 7208)How to confirmFix
More than 10 DNS-querying terms: include, a, mx, ptr, exists and redirect count, nested includes included; ip4, ip6, all and exp do notExpand every include recursively and count; many record checkers do thisRemove retired suppliers, replace a and mx with ip4/ip6, move suppliers to their own subdomain MAIL FROM
More than two void lookups (a term returning no answer or NXDOMAIN)Resolve each included name; look for NXDOMAIN from a supplier that changed its includeRemove dead includes
Two or more SPF records on the same namedig TXT returns two strings starting v=spf1Merge into one record; a second record often appears when a provider's setup wizard adds its own
mx term resolving to more than 10 address recordsCount the A/AAAA records behind each MX hostReplace with explicit ip4/ip6
Syntax error: unknown mechanism, typo such as inlcude:, stray charactersValidate the record; check copied quotes and spacingCorrect the syntax. TXT strings over 255 octets must be split; they are joined without spaces, so keep the space inside a string

RFC 7208 also says the ptr mechanism should not be published; it is slow, costs lookups and some receivers ignore it. If your record still has it, remove it while you are there.

SPF temperror

Temperror points at your DNS, not your record: slow or failing authoritative servers, DNSSEC validation failures, or responses too large for UDP that the receiver cannot retry over TCP. Check authoritative response times from more than one network and see the DNS Investigation with dig and nslookup Guide.

DKIM failures: diagnosis and fix

RFC 6376 gives informative failure texts that many verifiers echo in logs and reports. Map the text to the cause:

Verifier text (RFC 6376 s6.1)Likely causeWhere to look and fix
PERMFAIL (body hash did not verify)Body changed after signing: disclaimer, footer, link rewriting, list footer, character set conversionSend the same message direct to a test inbox and via each hop. If it passes direct, the hop that adds content is the cause. Sign after the last change, or have the gateway sign
PERMFAIL (signature did not verify)Signed headers changed (Subject tag such as [EXTERNAL] or a list prefix), or the published public key does not match the signing private keyCompare the h= list with headers modified in transit; compare the DNS key with the platform's current key after any rotation
PERMFAIL (no key for signature) / TEMPFAIL (key unavailable)No TXT record at <selector>._domainkey.<d=>, typo in the CNAME, or DNS not answeringdig TXT s1._domainkey.yourdomain.example; many platforms publish via CNAME, so check the chain resolves
PERMFAIL (key revoked)Key record has an empty p=A rotation retired the key while the platform still signs with it; republish or switch selector
PERMFAIL (key syntax error)Key pasted with line breaks, quotes or truncated across TXT stringsRe-publish the key exactly as the platform provides it
PERMFAIL (signature expired)x= passed before verification, often on delayed or queued mailLengthen the signer's expiry; check queue delays
PERMFAIL (From field not signed)h= omits From, which RFC 6376 requiresSigner misconfiguration; fix on the platform
dkim=policy or a receiver key-length noticeKey too short for the receiver; Google requires at least 1024-bit keys and recommends 2048Rotate to a 2048-bit key on a new selector
  • Canonicalisation: the RFC 6376 default is simple/simple, which tolerates almost no change. If the signer allows it, c=relaxed/relaxed survives header folding and whitespace changes that intermediaries routinely make. It will not survive added content.
  • Do not use l= to survive footers: RFC 6376 warns that a body length limit lets content be appended without breaking the signature, and l=0 allows complete alteration of the text.
  • Testing flag: a key record with t=y asks verifiers to treat failures like unsigned mail. Remove it once signing is stable, or failures will hide in plain sight.

DMARC fails while SPF or DKIM pass: alignment

This is the most common pattern in aggregate reports for organisations using third-party senders. RFC 9989 requires an authenticated identifier that aligns with the Author Domain (RFC 5322 From). In relaxed mode (adkim=r, aspf=r, the default) both must share an organisational domain; in strict mode they must be identical.

Header evidenceDiagnosisFix
spf=pass smtp.mailfrom=bounce.esp.example, dkim=pass header.d=esp.example, From is your domainSupplier authenticates as itself. Nothing alignsConfigure the supplier's custom DKIM (your d=, usually CNAME selectors) and, where offered, a custom return-path subdomain of yours
dkim=pass header.d=mail.yourdomain.example, From yourdomain.example, DMARC failsStrict alignment adkim=s requires an exact matchSign with the From domain or relax to adkim=r deliberately
DMARC fail on a subdomain you never useSpoofing, governed by sp or the new np tag for non-existent subdomainsNo fix needed if the policy enforces; set np=reject if not
dmarc=permerror or no DMARC resultTwo DMARC records at _dmarc (RFC 9989 discards all of them), or the first tag is not v=DMARC1Publish exactly one valid record
Policy applied one level lower than publishedt=y test mode under RFC 9989Intended during rollout; remove when ready

RFC 9989 (Standards Track, May 2026) obsoletes RFC 7489, removes pct, and finds the organisational domain by a DNS tree walk instead of the Public Suffix List. A receiver still on the older logic may show results that differ from one that has moved; see the DMARCbis Changes Guide. Microsoft's documentation still shows pct.quarantine and pct.reject actions for records with pct below 100.

Forwarders, mailing lists and ARC

  • Symptom: aggregate reports show DMARC failures from IPs belonging to universities, forwarding services or list servers, with SPF fail and DKIM fail or pass.
  • Diagnosis: if DKIM passes for your domain, DMARC passes and the SPF fail is harmless. If DKIM also fails, the forwarder modified the message (list footers and Subject tags are the usual cause).
  • What you control: DKIM on every source, with relaxed canonicalisation, and short, stable headers. You cannot fix a third party's list.
  • ARC: RFC 8617 is Experimental (July 2019). It records earlier authentication results in ARC-Authentication-Results, ARC-Message-Signature and ARC-Seal headers, with a chain status of cv=none, fail or pass. A receiver MAY use a trusted chain to override a DMARC failure as local policy (Microsoft reason code 130 shows it did); senders cannot require it.

Diagnosis workflow and rollback

  1. Capture evidence: one full failing message, its bounce text, and the last seven days of aggregate reports for the source IP.
  2. Identify the source: map the connecting IP to a system in your sending inventory. An unknown source is a spoofing or shadow IT finding, not a configuration fault.
  3. Read the three results in the Authentication-Results header and decide: mechanism failure, or alignment failure.
  4. Reproduce with a test send from the same platform to mailboxes at two providers, before and after the change.
  5. Change one record at a time, with a lower TTL set in advance so a mistake can be reverted quickly. Keep the previous record text in your change ticket.
  6. Roll back the policy only as a last resort: if a critical stream is being rejected and the fix needs supplier work, apply t=y or a lower policy for a fixed period with an owner and an end date, rather than leaving the domain unprotected indefinitely.
  7. Confirm in reports 48 to 72 hours later that the source now passes aligned.

Where identity fits

Every sending source is a non-human identity: a DKIM private key held by a supplier, an SMTP credential in an application, an email API key in a web plugin. Several failures above (keys revoked during rotation, undocumented senders, orphaned includes) are identity lifecycle failures. Give each source an owner and track its keys like any other secret; the Gravity SMTP CVE-2026-4020 incident exposed email API keys from WordPress sites, and mail sent with a stolen key authenticates perfectly.

Detection and measurement

  • Aligned pass rate per source: percentage of volume from each known source passing DMARC aligned; target above 99% for every source before enforcement.
  • Unknown-source volume: messages from IPs not in the inventory, trended weekly.
  • SPF lookup headroom: current DNS-querying term count against the limit of 10, checked on every record change.
  • DKIM key age and length: selectors older than your rotation period or under 2048 bits.
  • Bounce codes: count of 5.7.515, 5.7.26 and DMARC-named rejections in outbound logs, alerting on any rise.
  • Time to diagnose: from first bounce report to identified cause.

Common failure patterns

  • Fixing SPF for a DKIM problem: adding includes until the record hits permerror, when the real fault was a footer breaking the body hash.
  • Two records after a supplier wizard: a second SPF or DMARC record silently voids both.
  • Rotation without overlap: the old selector is emptied before the platform stops signing with it, producing key revoked for in-flight mail.
  • Trusting the wrong header: reading an Authentication-Results header from an internal hop rather than the receiver's own.
  • Dropping to p=none indefinitely: an outage fix that becomes permanent and reopens the domain to spoofing.

Framework mapping

FrameworkReferenceRelevance
CIS Controls v8.1Safeguard 9.5 Implement DMARCRequires DMARC with SPF and DKIM
NIST SP 800-53 Rev. 5SI-8 Spam Protection; SC-20 Secure Name/Address Resolution Service; AU-6 Audit Record ReviewReceiving protections, DNS integrity, report review
NIST CSF 2.0PR.AA-03; DE.CM-09Authenticating services; monitoring for adverse events
ISO/IEC 27001:2022A.5.14 Information transfer; A.8.16 Monitoring activitiesProtecting email transfer; monitoring reports
MITRE ATT&CKT1566 Phishing; T1598 Phishing for InformationTechniques enforced DMARC makes harder with your exact domain

Practitioner checklist

  • Diagnose from the receiver's Authentication-Results header or compauth code, not from your own DNS view.
  • Decide mechanism failure or alignment failure before changing anything.
  • Keep the SPF record under 10 DNS-querying terms and two void lookups, with exactly one record.
  • Publish exactly one DMARC record starting v=DMARC1.
  • Configure custom DKIM with your domain on every third-party sender.
  • Rotate DKIM keys with overlapping selectors and 2048-bit keys.
  • Find and fix the hop that modifies signed content instead of using l=.
  • Lower TTLs before changes and record the previous value for rollback.
  • Time-box any policy downgrade with an owner and an end date.
  • Map every failing source IP to an owned sender in the inventory.

Standards and references

Related NHI Mgmt Group resources: DMARC, SPF and DKIM Guide · DMARCbis Changes Guide · Email Authentication Checklist · Email Sending Sources Inventory Template · DNS Investigation with dig and nslookup Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 11 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org