SPF, DKIM, and DMARC: three acronym soups that keep your emails out of spam
You set up your newsletter, wrote something worth reading, clicked Send — and the emails land in spam. Or worse: someone starts sending messages from your domain, and you find out when angry customers call. Both problems come down to three DNS records. Without them in 2026, bulk email simply does not reach the inbox.
Why email needs authentication at all
Email was designed in the 1970s for a few hundred researchers who all trusted each other. Nobody thought about forgery. SMTP lets you put any return address in the From field — technically you can send a message from president@whitehouse.gov and a receiving server will accept it. That is exactly how phishing works: an attacker sends from your bank's domain, you click the link, money disappears.
SPF, DKIM, and DMARC are the patches for that gap. Three separate mechanisms, one shared question: "Did this message actually come from whoever appears in the From field?"
Each works differently. Together they cover almost every spoofing scenario.
SPF: the allowlist of authorized servers
Sender Policy Framework. The concept is straightforward: you publish a TXT record in your domain's DNS that lists every IP address and service allowed to send mail on your behalf. That's it.
When Gmail receives a message from yourdomain.com, it queries DNS, finds the SPF record, and compares the sending IP against the list. Match — fine. No match — suspicious.
A typical SPF record looks like this:
This says: Google Workspace and SendGrid servers are allowed to send for our domain. Everyone else is rejected (-all). If you also use Mailchimp, add another include.
Common SPF mistakes
- Forgetting to add a new service. You connect a new ESP and start sending — but SPF doesn't know about it. Emails from that service go straight to spam.
- Too many DNS lookups. SPF allows a maximum of 10 DNS lookups. Every
includeis one lookup, and nested includes count too. Exceed the limit and SPF breaks silently. - Soft
~allinstead of hard-all. The tilde means "maybe not us, maybe us." The hyphen means "definitely not us, reject it." Use~allonly while debugging.
SPF is the first line of defense, but it has one real weakness: it checks the sending server's IP, not the message content. If an attacker compromises your ESP account, SPF won't stop them — the mail comes from an authorized IP. That is where DKIM comes in.
DKIM: a digital signature on every message
DomainKeys Identified Mail takes a different approach. Every outgoing message gets signed with a private key. Your domain's DNS holds the matching public key. The recipient pulls the signature from the message headers, retrieves the public key from DNS, and verifies two things: the message was not modified in transit, and it was genuinely signed by the domain owner.
In practice, DKIM is what gets misconfigured most often — not because it's hard, but because most ESPs generate the keys automatically, so senders don't realize what actually happened.
What the DNS record looks like:
selector1 is the key identifier. You can have several: one for Google, one for SendGrid. Each service gives you its own selector and public key. You add a CNAME or TXT record to DNS and you're done.
What DKIM does in practice
It protects against modification. If a spammer intercepts your message and swaps out a link, the signature breaks. The recipient's server sees the tampering.
DKIM also builds reputation over time. Gmail and other providers tie your DKIM signature to your sending history: opens, complaints, bounces. A clean DKIM reputation is a direct path to the inbox.
Domains with valid DKIM and a 2048-bit key consistently show 12-18% better Gmail inbox placement than domains using a 1024-bit key or no DKIM at all.
On key length: 1024 bits is outdated. Google recommends 2048. If your ESP still generates 1024-bit keys, that's worth a conversation with their support team or a good reason to switch.
DMARC: the policy for what happens when checks fail
Domain-based Message Authentication, Reporting and Conformance. Long name, simple job: DMARC tells receiving servers what to do with a message that fails SPF or DKIM.
Three policy options:
p=none— do nothing, just send reports. Monitoring mode.p=quarantine— route suspicious messages to spam.p=reject— refuse the message entirely. It never arrives.
A minimal record:
The rua field is the address where aggregate reports arrive. These are XML files that show exactly who is sending mail from your domain, how many messages passed SPF and DKIM, and how many failed. Genuinely useful data.
Reading DMARC reports
The XML format is not pleasant to read directly. Free tools handle the parsing: DMARC Analyzer, Postmark DMARC, EasyDMARC. They turn the raw XML into charts showing who sent from your domain, from where, and whether the checks passed.
About 90% of people set p=none and forget the reports exist. That's like installing a security camera and never looking at the footage. The record is technically there; it's doing nothing.
How SPF, DKIM, and DMARC work together
Each one alone has gaps. SPF checks the server but not the content. DKIM signs the content but doesn't say what to do with failures. DMARC brings both together and adds the enforcement policy.
Here is the sequence when Gmail receives your message:
- Check SPF: is the sending IP on the authorized list?
- Check DKIM: is the signature valid, was the message unmodified?
- Check DMARC: did at least one check pass, and does the From domain align with the SPF or DKIM domain?
- If DMARC passes — the message moves on to reputation and content scoring. If it fails — the DMARC policy kicks in.
The critical word there is alignment. DMARC requires the domain in the From header to match the domain from SPF or DKIM. Without that match, the check fails even when SPF and DKIM are individually valid.
Step-by-step setup: 30 minutes total
You don't need to be a sysadmin. You need DNS panel access and a list of every service sending mail from your domain.
Step 1. SPF
List every service that sends email on behalf of your domain: Google Workspace, SendGrid, your CRM, your own mail server. Write them all down.
Create a single TXT record at the root of your domain (not a subdomain). Start with v=spf1, add an include: for each service, end with -all. Count the DNS lookups — stay under 10.
Step 2. DKIM
Go into each sending service's settings and find the authentication or DKIM section. The service will give you a CNAME or TXT record with its public key. Add it to DNS — it usually looks like selector._domainkey.yourdomain.com. Wait 10-30 minutes for DNS to propagate, then click Verify in the service settings.
Step 3. DMARC
Create a TXT record for _dmarc.yourdomain.com. Start with p=none — don't jump to reject on day one. Add rua=mailto:your@address so reports start flowing. Watch for two to four weeks. If everything looks clean, move to quarantine. After another month with no issues, switch to reject.
Rushing to reject is a real risk. If you missed a sending service in your SPF record or skipped DKIM for one channel, reject will block your own legitimate mail. The p=none stage gives you time to find and close every gap before enforcement.Mailbox provider requirements in 2026
Since February 2024, Gmail and Yahoo have enforced strict rules for senders above 5,000 messages per day: SPF or DKIM is mandatory, and DMARC is required at minimum p=none. Without it, messages don't go to spam — they are rejected at the SMTP connection.
Outlook and Apple Mail have tightened filtering in 2025 along similar lines. The direction is clear: full authentication is table stakes, not optional hardening.
Even below the 5,000-per-day threshold, missing authentication hurts sender reputation. That means Promotions tab instead of inbox, lower open rates, and worse ROI on every campaign you run.
Common problems and how to fix them
Multiple SPF records. A domain can have only one SPF TXT record. If you added a second one, both are invalid — receiving servers treat this as a configuration error. Merge all include directives into a single line.
No DKIM key rotation. The same key for three years is poor hygiene. If the key leaks, an attacker can sign messages as your domain. Rotate every 6-12 months. Google Workspace handles this in two clicks.
Forwarding breaks SPF. When a subscriber forwards your message to a colleague, the forwarding server's IP won't be in your SPF record. That's expected — which is why DMARC only requires one of the two checks to pass, not both. DKIM usually survives forwarding because the message body doesn't change.
Subdomains without their own policy. DMARC does not automatically apply to subdomains. If you have p=reject for yourdomain.com but no record for mail.yourdomain.com, an attacker can send from the subdomain unchecked. Add sp=reject to your DMARC record to cover subdomains as well.
How to verify everything is working
The fastest check: send a message to your own Gmail and open Show original (three dots → Show original). Look for the Authentication-Results header. You want to see spf=pass, dkim=pass, and dmarc=pass. All three — you're set.
Online tools also help: MXToolbox, mail-tester.com, Google Postmaster Tools. If you send over 1,000 messages a day, Postmaster Tools is worth setting up regardless — it shows domain reputation, authentication rates, and spam complaint rates for free.
Authentication plus list hygiene: the full picture
SPF, DKIM, and DMARC are the foundation. They are not a guarantee of inbox placement. You can configure all three perfectly and still hit spam if you are sending to invalid addresses.
A hard bounce rate above 2% is a red flag for every major provider. Spam traps in your list are worse. No DMARC policy at p=reject will save you if a quarter of your contacts are dead addresses.
The order is straightforward: configure SPF, DKIM, and DMARC first (30 minutes), then clean the list (a few minutes more).
Authentication configured? Good. Now make sure your list doesn't undermine it. Upload your list to uChecker — in a couple of minutes you'll see how many addresses are invalid, how many are risky, and how many spam traps are hiding in your database.
