Three letters, three records, one big goal: make sure nobody can send email pretending to be you. SPF, DKIM, and DMARC each solve a different piece of the problem, and they only fully work when all three are in place. This guide explains what each one does, what records you need to publish, and how to roll it out without breaking your existing email.
The problem they solve
The original email standard (SMTP) is from 1982 and has no built-in way to verify who actually sent a message. Anyone can connect to a mail server and claim "From: ceo@your-company.com" — and historically, it would be delivered. That's the spoofing problem. SPF, DKIM, and DMARC are bolt-on standards that close the gap.
SPF — "which servers can send for me?"
SPF (Sender Policy Framework) is a TXT record at your domain's apex that lists which IP addresses and domains are authorized to send email From your domain. Receiving servers look at the IP that connected to them, look up your SPF record, and check whether that IP is on the list.
example.com. IN TXT "v=spf1 include:_spf.google.com include:mailgun.org -all"
Breaking that down:
v=spf1— version marker. Always present.include:_spf.google.com— "also accept whoever Google's SPF record authorizes." Used because you don't want to maintain Google's IP list yourself.include:mailgun.org— same for your transactional email provider.-all— "reject anyone not listed above." The leading dash is the strict version.~allis softfail (please mark as suspicious),?allis neutral (no opinion),+allmeans accept everyone — a disaster.
The 10-lookup limit. SPF has a hardcoded rule that resolving the record can require no more than 10 DNS lookups. Every include:, every a or mx mechanism counts. If you exceed it, your SPF "permanently fails" and receivers may reject your mail. Fix: flatten the record (resolve includes into IP ranges with a service like dmarcian or autospf) or trim the senders.
The fundamental SPF limitation. SPF only checks the envelope From address (the SMTP MAIL FROM), not the visible From header. So if your mailing list forwards a message, SPF can break, because the forwarder is now sending from a different IP than your original. That's where DKIM and DMARC come in.
DKIM — "this message was actually signed by me"
DKIM (DomainKeys Identified Mail) puts a cryptographic signature on every outbound email. The sending server hashes specific headers plus the body, signs the hash with a private key, and attaches the signature in a header. Your DNS publishes the matching public key. Any receiver can verify.
DKIM uses "selectors" so you can have multiple keys per domain (e.g., one per sending service). The DNS record sits at {selector}._domainkey.{domain}:
google._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."
The p= value is your base64-encoded RSA public key. Most providers (Google Workspace, Microsoft 365, Mailgun, SendGrid, SES) generate this for you and give you the exact TXT record to add. You never see or handle the private key directly.
Why DKIM survives forwarding. Because the signature is attached to the message itself, mailing list servers and forwarders can pass the message along and the signature still verifies. SPF breaks on forwarding; DKIM doesn't.
Common gotcha. DKIM keys longer than 2048 bits split into multiple TXT strings — your DNS UI must keep them as one logical value or signatures will fail.
DMARC — "what should receivers do with failures?"
DMARC (Domain-based Message Authentication, Reporting and Conformance) ties SPF and DKIM together. It does two things:
- Tells receiving servers what policy to apply when a message claiming to be From your domain fails SPF or DKIM.
- Asks receivers to send you periodic reports about who is sending mail as your domain.
The record lives at _dmarc.{domain}:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; adkim=s; aspf=s"
Breaking it down:
p=reject— the policy. Three values exist:none(just monitor),quarantine(send to spam),reject(refuse delivery). Start atnone, end atreject.rua=mailto:...— where to send daily aggregate reports. These are XML files describing which IPs sent mail "as you" and whether they passed SPF/DKIM. You'll want to parse them with a service like Postmark DMARC, dmarcian, or Valimail.adkim=s; aspf=s— strict alignment. The signing domain (DKIM) and the envelope From domain (SPF) must match the header From domain exactly, not just be a subdomain.
The rollout sequence (do not skip steps)
Going from no DMARC to p=reject in one step is a great way to block your own real mail. The safe sequence is:
- Publish SPF. Start with all known senders included. End in
-allas soon as you're sure the list is complete. - Publish DKIM for every sending service. Most providers walk you through this; the result is one TXT record per provider, each at a unique selector.
- Publish DMARC at
p=nonewith arua=reporting address. Don't enforce anything yet — just collect data. - Review reports for 2–4 weeks. Look for legitimate senders that are failing alignment. Common culprits: marketing tools sending as your domain without DKIM, in-house apps using a third-party SMTP relay without SPF authorization, payroll systems, calendar invites, support ticket systems.
- Fix the failing legitimate senders by adding them to SPF or enabling DKIM. Don't move forward until the reports are clean.
- Upgrade to
p=quarantinefor another 2–4 weeks. Receivers will send suspected forgeries to spam. - Upgrade to
p=reject. Forgeries are now refused at the SMTP transaction. You're done.
Total elapsed time: 4–10 weeks for a single domain. Worth it.
Adjacent records: MTA-STS and BIMI
Once you're at p=reject, two more records get you the rest of the way:
- MTA-STS forces sending servers to use TLS when delivering mail to you, preventing downgrade attacks. Requires a TXT record and a small HTTPS policy file.
- BIMI publishes your brand logo, so Gmail and Yahoo show it next to authenticated messages from your domain. Requires DMARC at
p=quarantineor stricter, a properly formatted SVG, and (for Gmail) a Verified Mark Certificate.
Verifying your setup
The fastest sanity check: paste your domain into DNS Export's email audit. It checks SPF and DMARC syntax, probes the nine most common DKIM selectors, detects your mail provider from MX, and emits a copy-pasteable record for anything that's missing or weak.