SPF, DKIM and DMARC explained: why your emails land in spam
Your invoices reach customers' spam folders, or bounce outright. Nine times out of ten the content isn't the problem. The receiving servers simply can't confirm the mail is really from your domain. Three DNS records decide that.
The three records in plain words
SPF: who may send
SPF is a TXT record on your domain that lists the servers allowed to send its mail. A typical one, for a business using Google Workspace and a newsletter tool:
v=spf1 include:_spf.google.com include:servers.mcsv.net ~all
Each include: pulls in a provider's list. The ending says what to do with everything else: -all means “reject”, ~all means “treat with suspicion”. SPF checks the hidden envelope sender (the Return-Path), not the From line people see, which is why it isn't enough on its own.
The trap: SPF allows at most ten DNS lookups while it's evaluated. Each include, a, mx and exists counts, including the ones inside the providers' lists. Add one service too many and SPF fails for every message, silently.
DKIM: a signature on every message
Your mail service signs each outgoing message with a private key, and publishes the public key in DNS under a selector, at selector._domainkey.yourdomain. The receiver checks the signature; if it matches, the message really passed through a server holding your key and wasn't altered on the way. You don't write DKIM records by hand: each mail service gives you the record to publish, and you turn signing on in its settings.
DMARC: tie it to the From address, and set a policy
DMARC lives at _dmarc.yourdomain. It says: a message passes only if SPF or DKIM passes for the same domain as the From address (that's called alignment), and here's what to do when it doesn't.
v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain
p=none only collects reports; p=quarantine sends failures to spam; p=reject refuses them. The rua address receives daily summary reports from big receivers, listing every server that sent mail claiming to be you. Those reports are how you find the services you forgot.
A worked example: a domain that sends no email at all
We ran iplover's domain report on example.com, the documentation domain, on 9 November 2026. Its email section, as shown:
| MX | Note: Declares that it does not receive email (null MX). |
|---|---|
| SPF | OK: SPF ends in -all: email from other servers should be rejected (0 of 10 lookups). Record: v=spf1 -all |
| DMARC | OK: DMARC is p=reject: failing email is rejected. Record: v=DMARC1;p=reject;sp=reject;adkim=s;aspf=s |
| DKIM | Note: No DKIM key found among the common selectors (google, selector1, selector2, default, k1, s1, mail). The domain may still use DKIM with a different selector. |
This is what a domain that never sends mail should look like, and it's worth copying for any domain you own but don't use for email:
v=spf1 -alllists no allowed servers at all, so every message claiming to be from it fails SPF.p=rejectwithsp=rejectasks receivers to refuse failures for the domain and its subdomains.adkim=sandaspf=srequire exact (strict) alignment rather than allowing subdomains.- A null MX record says the domain accepts no mail either.
The DKIM note is honest about its limit: no key at the selectors we tried. A domain that sends nothing has no reason to publish one. For a domain that does send, “not found” can also mean a selector we didn't guess; the headers of a message you sent (look for s= in the DKIM-Signature line) tell you the real one.
Check your own domain
dig +short TXT yourdomain.com | grep spf1
dig +short TXT _dmarc.yourdomain.com
dig +short TXT selector._domainkey.yourdomain.com # use your real selector
On Windows: nslookup -type=TXT _dmarc.yourdomain.com. Or run the domain report, which does all of this and counts SPF lookups for you.
The best test of all: send a message to a Gmail account you control, open it, choose Show original, and read the SPF, DKIM and DMARC lines at the top. That's exactly what the receiver concluded about you.
If your mail lands in spam: the fix list
| What you find | What it means | What to do |
|---|---|---|
| No SPF record | Receivers can't tell which servers are yours | Publish one listing every service that sends for you, ending in ~all at first. |
| Two SPF records | That's an error: SPF fails | Merge them into one record. |
| SPF over 10 lookups | SPF fails for everything | Remove services you no longer use; ask providers for a smaller include, or move one service to a subdomain. |
| No DKIM for a service (newsletter, invoicing, CRM) | Its mail can only pass DMARC through SPF, if at all | Turn on DKIM signing with your own domain in that service's settings and publish its record. |
| No DMARC record | Large providers increasingly expect one | Start with p=none and a report address. Read the reports for a few weeks. |
| DMARC fails for a service you use | It sends with your From address without alignment | Set up DKIM with your domain there, or send it from a subdomain with its own records. |
| All three pass, still spam | Reputation or content | Check the sending address on blocklists, send only to people who asked, and make unsubscribing easy. |
Once the reports show only your own services passing, tighten DMARC step by step: p=quarantine, then p=reject. Going straight to reject before you've found every sender is how companies lose their own invoices.
What these records can't do
SPF, DKIM and DMARC protect your exact domain from being forged. They don't stop someone registering a similar domain, they don't make spammy mail welcome, and they say nothing about whether a message's content is honest. They're the minimum that lets receivers trust your domain, not a guarantee of the inbox.
Sources
Official documents we used to check the facts in this guide.