Anyone can put your domain in the From line of an email. SMTP was designed in the 1980s and never checked. SPF, DKIM and DMARC are the three DNS records that let receiving mail servers tell real mail from forgeries, and since 2024 Gmail and Yahoo require all three from anyone sending in bulk. Here's what each one does, how they fit together, and the mistakes that quietly break them.
You can check all three for any domain with the email authentication checker. It reads the records, follows every SPF include, and explains each problem it finds.
What does SPF do?
SPF (Sender Policy Framework) is a TXT record on your domain that lists the servers allowed to send mail for it:
example.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net -all"When a message arrives, the receiving server looks up the SPF record for the domain in the envelope sender (the Return-Path, not the visible From) and checks whether the connecting IP address is on the list.
The all at the end decides what happens to everyone else:
| Ending | Name | Meaning |
|---|---|---|
-all | Fail | Reject mail from unlisted servers |
~all | Softfail | Accept it but treat it as suspicious |
?all | Neutral | No opinion, so no protection |
+all | Pass | Anyone may send. Never use this |
~all is the common choice, because DMARC (below) is what actually enforces the policy.
Why SPF fails with "too many DNS lookups"
SPF caps a single check at 10 DNS lookups. Every include, a, mx, ptr, exists and redirect counts, and so does every lookup inside the records you include. ip4 and ip6 are free.
That limit is easy to hit without noticing. include:_spf.google.com alone costs 4 lookups, because Google's record includes three more. Add Microsoft 365, a newsletter tool, a CRM and a helpdesk, and you're at 11 or 12. Past 10, receivers return a permerror and SPF fails for all your mail, not just the newest sender.
Ways to get back under the limit:
- Remove includes for services you no longer use. Old ones pile up over the years.
- Replace an include with that provider's
ip4/ip6ranges, if they publish stable ones. - Send marketing mail from a subdomain like
news.example.com, which gets its own SPF record and its own 10 lookups.
The other classic mistake is two SPF records. Adding a second v=spf1 TXT record for a new provider doesn't extend the first; it breaks both. Merge them into one.
What does DKIM do?
DKIM (DomainKeys Identified Mail) signs every outgoing message with a private key. The matching public key sits in DNS under a selector:
google._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."The signature travels in a DKIM-Signature header, whose d= tag names the signing domain and s= tag names the selector. The receiver fetches the key and verifies that the signed headers and body weren't altered on the way.
Unlike SPF, DKIM survives forwarding, because the signature travels with the message instead of depending on which server delivered it.
Two things to check:
- Key size. 1024-bit RSA keys are still common but weak. Use 2048 bits; most providers offer it now.
- Selector names. There's no way to list a domain's selectors through DNS, so a checker has to guess or be told. If yours isn't found, open a message you sent, find the
DKIM-Signatureheader, and look fors=.
What does DMARC do?
SPF and DKIM each verify a domain, but neither checks the domain people actually see in the From line. A spammer can pass SPF for their own domain while showing yours in From. DMARC closes that gap with alignment: it passes only if SPF or DKIM passes for the same domain as the From address.
DMARC also tells receivers what to do when that check fails, and where to send reports:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"| Tag | Meaning |
|---|---|
p | Policy: none, quarantine (spam folder) or reject |
rua | Where to send daily aggregate reports |
sp | Policy for subdomains, if different from p |
pct | Percentage of failing mail the policy applies to |
adkim / aspf | r (relaxed, subdomains count) or s (strict, exact match) |
How to move DMARC from p=none to p=reject
p=none is monitoring only: spoofed mail is still delivered. It's the right place to start, but plenty of domains never leave it. A safe path:
- Publish
p=nonewith aruaaddress. Receivers start sending aggregate reports listing every server that sends as your domain. - Read the reports for two to four weeks. Look for legitimate senders that fail, such as a billing system or a support desk. Fix each one by adding it to SPF or, better, by setting up DKIM signing with your domain.
- Move to
p=quarantine. Optionally usepct=25and raise it gradually. - Move to
p=rejectonce the reports show only forgeries failing.
Reaching p=quarantine or p=reject also unlocks BIMI, which shows your logo next to messages in Gmail, Yahoo and Apple Mail.
What about domains that never send email?
Parked domains are favorite spoofing targets because nobody watches them. Lock them down with three records:
example.org. TXT "v=spf1 -all"
_dmarc.example.org. TXT "v=DMARC1; p=reject"
example.org. MX 0 .The last one is a "null MX". It says the domain accepts no mail at all.
Check your domain
Run your domain through the email authentication checker. It counts SPF lookups across every include, finds DKIM keys under common selectors (or the one you enter), checks your DMARC policy and tags, and scores the setup with a fix for each problem. It also checks MTA-STS and TLS-RPT, which protect mail coming in to your domain. To look at an individual record by hand, use the DNS lookup tool with record type TXT.