Understand what SPF, DKIM, and DMARC each prove, read the records and Authentication-Results headers, diagnose failures, and roll out DMARC safely.
The problem these records solve
Email was designed without sender verification: anyone can write any address in the "From" line. SPF, DKIM and DMARC are three DNS-based mechanisms that let a receiving server check whether a message is really authorized by the domain it claims. If you run a domain you need them so your mail is delivered and your domain is harder to spoof; if you investigate suspicious mail you need to read their results.
First, understand that a message carries two different sender identities. The envelope sender (the SMTP "MAIL FROM", recorded as the Return-Path header) is where bounces go. The header From is the address users see. Attackers can make these differ, and the three protocols each look at a different one.
SPF: which servers may send for the envelope domain
SPF is a TXT record at the domain itself that lists the servers allowed to send mail using that domain as the envelope sender. The receiver compares the connecting server's IP address with the list. A typical record:
example.com. IN TXT "v=spf1 include:_spf.mailer.example.net ip4:203.0.113.0/24 -all"
Each term is a mechanism: ip4/ip6 list addresses, include pulls in another domain's SPF policy (used for third-party senders), a and mx authorize the domain's own hosts. The final all says what to do with everyone else: -all fail, ~all soft fail, ?all neutral, +all allow everyone. The analysis of the record above reads: final policy -all, 1 DNS-lookup mechanism(s), no findings.
Rules that cause most real-world failures:
- Exactly one SPF record per domain. Two cause a permanent error (
permerror) and SPF fails. - The 10-lookup limit. Each
include,a,mx,ptr,existsandredirectcosts a DNS lookup, nested includes included. Exceeding ten givespermerror. A record with eleven includes is flagged: This record directly contains 11 DNS-lookup mechanisms; SPF allows at most 10 total lookups (including nested includes), so this is likely to exceed the limit and cause a PermError. +alldefeats the purpose. The analyzer flags it: Policy is +all, which authorizes every sender on the internet to send mail as this domain — this effectively disables SPF protection and is potentially unsafe.- SPF authenticates the envelope domain, not the visible From address, and it breaks when mail is forwarded because the forwarder's IP is not in the original domain's list.
DKIM: a signature on the message
DKIM lets the sending system sign selected headers and the body with a private key. The matching public key is published in DNS under a selector, which lets a domain use several keys at once (one per mail provider, or per rotation):
selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN..." (key truncated)
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=selector1;
h=from:to:subject:date; bh=...; b=...
In the signature header, d= is the signing domain, s= the selector, h= lists the signed headers, bh= is a hash of the body, and b= is the signature. The receiver looks up s._domainkey.d, verifies the signature, and records dkim=pass or fail. Because the signature covers the content, DKIM generally survives forwarding but fails if anything modifies the signed parts, such as a mailing list adding a footer (a body hash did not verify error). Public keys of 2048 bits are now common. The selector cannot be discovered from the domain alone; you need it from the provider or from a message's DKIM-Signature header, which is why the DNS Security Checker asks for it.
DMARC: tying them to the visible From address and setting policy
On their own, SPF and DKIM do not check the address people see. DMARC adds that link, through alignment: a message passes DMARC if SPF or DKIM passes and the authenticated domain matches the From-header domain (relaxed alignment allows a subdomain of the same organizational domain; strict requires an exact match). The policy tells receivers what to do when it fails, and requests reports:
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=25; rua=mailto:[email protected]"
The tool's reading of that record: policy quarantine, applied to 25% of failing mail, with aggregate reports requested. The policy values are none (monitor only), quarantine (treat as suspicious, commonly spam folder), and reject (refuse). Other tags include sp (policy for subdomains), adkim and aspf (alignment modes), rua (aggregate reports) and ruf (failure reports, rarely honored).
Reading the results in a message
The receiving server records its verdicts in an Authentication-Results header (RFC 8601):
Authentication-Results: mx.provider.example;
spf=pass smtp.mailfrom=bounce.example.net;
dkim=pass header.d=example.net header.s=selector1;
dmarc=pass header.from=example.net
(illustrative)
smtp.mailfrom is the envelope sender SPF checked; header.d is the DKIM signing domain; header.from is the visible From domain. DMARC passes here because the DKIM domain (example.net) aligns with header.from, and the SPF domain (bounce.example.net) is a subdomain, which relaxed alignment accepts. Paste headers into the Email Header Analyzer to see these verdicts laid out next to the delivery route.
A common puzzle: spf=pass and dkim=pass but dmarc=fail. This usually means a third-party service sent the mail: SPF passed for the service's bounce domain and DKIM was signed with the service's domain, so neither aligns with your From domain. The fix is to configure the service to sign with your own domain (and use a return-path on your domain) following its custom-domain instructions.
Passing is not trustworthy. An attacker who registers a look-alike domain can publish perfectly valid SPF, DKIM and DMARC for it. These checks prove a message is authorized by the domain it names, not that the domain is honest.
A safe rollout for your own domain
- Inventory every system that sends mail as your domain: your mail provider, marketing and ticketing platforms, billing, monitoring, forms, and devices.
- Publish one SPF record that includes each of them, ending with
~allat first. Take include values exactly as each provider documents. - Enable DKIM signing at every sender, using your own domain, and publish the selector records they give you.
- Publish DMARC with
p=noneand aruaaddress. Review the aggregate reports for a few weeks to find legitimate senders that fail. - Fix the failures, then move to
quarantine(optionally ramping withpct), and finallyreject. Tighten SPF to-allwhen you are confident the list is complete. - Protect domains that do not send mail with
v=spf1 -alland a DMARCp=rejectpolicy; add a null MX record (RFC 7505) if they also never receive mail.
Troubleshooting guide
- spf=permerror
- More than ten lookups, two SPF records, or a syntax error. Flatten or reduce includes and ensure a single record.
- spf=softfail or fail on forwarded mail
- Expected: the forwarder's IP is not authorized. DKIM (or ARC, RFC 8617, used by intermediaries to vouch for earlier results) is what keeps such mail passing DMARC.
- dkim=fail (body hash did not verify)
- Something altered the message after signing: a mailing-list footer, a gateway disclaimer, or content rewriting. Move the modification before signing or accept the failure for that path.
- dkim=none
- No signature present. Enable signing on that sender.
- dmarc=fail with spf and dkim pass
- Alignment failure, usually a third-party sender (see above).
- Legitimate mail rejected after moving to p=reject
- A sender was missing from your inventory. Review the aggregate reports, fix that sender, and consider stepping back to
quarantinewhile you do.
What the DNS Security Checker will tell you
Entering your domain (and a DKIM selector) gives the SPF mechanisms, final policy and findings; the DMARC policy and tags; the DKIM record at that selector; and the DNSSEC, CAA, MX and NS records. For comparison, the analysis of a record that ends in +all says: Policy is +all, which authorizes every sender on the internet to send mail as this domain — this effectively disables SPF protection and is potentially unsafe. These are configuration findings: the tool does not follow SPF includes recursively, and it does not verify the signature on any real message.
Tools used in this guide
- DNS Security Checker — Analyze SPF, DMARC, DKIM, DNSSEC, and CAA configuration for a domain, with each finding explained.
- Email Header Analyzer — Paste raw email headers to review the Received chain and SPF, DKIM, and DMARC results — processed locally in your browser.
- DNS Lookup — Query A, AAAA, CNAME, MX, NS, TXT, SOA, CAA, and SRV records for a domain.
- IOC Analyzer — Paste an IP, domain, URL, or file hash — the type is detected automatically and enriched with DNS, RDAP, TLS, and geolocation context.
References and further reading
- RFC 7208 — Sender Policy Framework (SPF)
- RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures
- RFC 7489 — Domain-based Message Authentication, Reporting, and Conformance (DMARC)
- RFC 8601 — Message Header Field for Indicating Message Authentication Status
- RFC 8617 — The Authenticated Received Chain (ARC) Protocol
- RFC 7505 — A "Null MX" No Service Resource Record
References are primary sources (standards and official documentation). Commands and sample output are illustrative; behavior can vary by operating system and software version.
Keep reading
- How to Investigate a Suspicious IP Address or Domain — A structured first-pass triage workflow for an IP address, domain, URL, or email: gather observable facts, separate them from inference, correlate with your own logs, and decide what to do next.
- How to Troubleshoot DNS Resolution Problems — A step-by-step method for diagnosing names that will not resolve, resolve to the wrong address, or work for some users and not others, using dig, nslookup, and public resolvers.