Every outgoing email from your domain carries a silent question: how does the receiving server know this message really came from you? The answer is a trio of DNS records — SPF, DKIM and DMARC. Get them right and your invoices, password resets and support replies land in inboxes. Get them wrong and two bad things happen at once: your legitimate mail silently vanishes into spam folders, and anyone on the internet can send convincing phishing email as your domain, because for most receivers, unsigned mail from an unconfigured domain is indistinguishable from yours.
This guide explains how the three mechanisms fit together, why the order you deploy them matters, and how to reach DMARC enforcement without a single lost message. To see what your domain currently publishes, run the free security scan — it validates SPF, DKIM and DMARC records as part of the Email Security check.
Table of contents
- The problem: SMTP has no built-in identity
- SPF: which servers may send for me
- DKIM: cryptographic proof of the message
- DMARC: the policy that ties it together
- The safe rollout, step by step
- The failures that fill spam folders
- Frequently asked questions
The problem: SMTP has no built-in identity
SMTP, the protocol email has run on since 1982, authenticates nothing. Any server on the internet can open a TCP connection to a mail exchanger and say MAIL FROM:<ceo@yourcompany.com>. The display name will render, the domain will render, and the only remaining signals are reputation heuristics. This is why "the CEO needs you to buy gift cards" works: the domain in the sender address carries no cryptographic weight unless you publish records that give it weight.
SPF, DKIM and DMARC attack this from three directions: which servers may send (SPF), cryptographic proof the message is intact and signed by the domain (DKIM), and what to do when both fail (DMARC).
SPF: which servers may send for me
An SPF record is a DNS TXT record listing every IP source allowed to send mail for your domain:
yourcompany.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.10 -all"
Reading it left to right: Google Workspace and SendGrid may send on your behalf, plus that one on-prem relay; -all means everyone else fails. The mechanism vocabulary is small: ip4:/ip6: for raw addresses, include: to pull in another domain's list (every SaaS sender publishes one — your CRM, your helpdesk, your newsletter tool), a/mx to reuse your own A and MX records, ~all (soft-fail) versus -all (hard-fail) for the catch-all.
Three operational rules save you from the classic SPF disasters:
- The 10-DNS-lookup limit. SPF evaluation may cost at most ten DNS lookups; each
include:,a,mxandredirectcosts one. Marketing stacks routinely need twelve. When the limit is exceeded, the result ispermerror— permanent failure — and receivers may treat your mail as unauthenticated. Consolidate includes and prune dead vendors; the scan counts your lookups for you. - No duplicate TXT records. Two
v=spf1TXT records on the same name is invalid — receivers pick one at random. If you have both"v=spf1 ..."and a stray legacy record, delete one. - Prefer
-allonce your inventory is complete.~allwas a sensible transitional setting; left forever, it tells aggressive receivers you are not confident in your own list, and they grade accordingly.
One subtlety that bites everyone: SPF validates the envelope sender (the MAIL FROM domain), not the From: header the recipient sees. A phishing mail can pass your SPF check perfectly — sent from the attacker's own server, SPF-authorized for the attacker's own domain — while displaying your domain in From:. Closing that gap is DKIM's job, and DMARC's.
DKIM: cryptographic proof of the message
DKIM (DomainKeys Identified Mail) has the sending server attach a digital signature to every message. The signature covers chosen headers and the body; the public key lives in DNS:
google._domainkey.yourcompany.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."
The selector (google here) plus the ._domainkey label tells receivers where to look; p= carries the RSA public key. The receiving server fetches the key, verifies the signature, and now knows two things no spoofed mail can fake: the message really passed through a server holding the domain's private key, and neither the signed headers nor the body were altered in transit.
Practical guidance:
- Use 2048-bit keys. 1024-bit DKIM keys are within modern cracking reach and some receivers already discount them.
- Sign with every system that sends. Each sender (Google, SendGrid, your ERP) has its own selector and key pair. A mail flow you forget to sign is a mail flow that fails DKIM.
- Rotate keys periodically. The DNS record makes rotation cheap: publish the new
p=, switch the signer, retire the old key. - Mind header over-signing subtleties on exotic relays — if a middleware rewrites
Subject:after signing, verification breaks. Sign headers that matter and configure relays to sign last.
Note again what DKIM does not do: it proves a domain signed the message, not that this domain matches the one in From:. An attacker can DKIM-sign spoofed mail with their own domain. Alignment is the missing piece — which is DMARC.
DMARC: the policy that ties it together
DMARC (Domain-based Message Authentication, Reporting and Conformance) answers the two questions the other records leave open:
- Does the authenticated domain match the visible
From:domain? This is alignment. SPF or DKIM must pass and the passing domain must align withFrom:(exact match, or same organizational domain under the relaxed mode that almost everyone uses). - What should the receiver do when it doesn't? Your published policy, in another TXT record:
_dmarc.yourcompany.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourcompany.com; adkim=r; aspf=r; pct=100"
The policy values are the deployment ladder:
p=none— monitor only. Mail is neither quarantined nor rejected; you just receive aggregate reports (rua): daily XML from Gmail, Microsoft and friends listing every message claiming to be your domain, whether it passed, and which IP sent it.p=quarantine— failures go to spam. Start withpct=25(a quarter of failing mail) and raise as reports confirm your legitimate flows pass.p=reject— failures bounced outright. The state that makes phishing as your domain essentially unviable, and the state Google and Yahoo have made mandatory in practice for bulk senders since 2024.
Read your first month of aggregate reports carefully. They will contain surprises: an ancient no-reply@ cron job, a partner sending on your behalf from an unlisted IP, a salesperson's third-party mail merge tool. Every legitimate flow you discover gets added to SPF or gets its own DKIM selector — that is precisely what p=none is for.
Two auxiliary tags are worth knowing: sp= sets a separate policy for subdomains (default: inherit p=), and fo=/ruf= configure failure (forensic) reports, which most providers no longer send — rely on rua aggregates.
The safe rollout, step by step
- Inventory every sender. Grep code for
smtp, check the marketing stack, the CRM, the billing system, the server cron jobs. Miss one and it shows up in reports atp=quarantine— better to find it now. - Publish SPF with everything found,
~all. Fix the lookup count now, while stakes are low. - Enable DKIM everywhere it's offered and publish each selector. Most SaaS senders have a "authenticate your domain" page; do all of them.
_dmarcatp=nonewithrua=. Collect 3–4 weeks of reports. Confirm your own flows pass alignment in the XML (look for your domain in thespf/dkimpass rows).p=quarantine; pct=25for a week, then 50, 100 — watching reports the whole time.p=reject. You now have cryptographic teeth. Keep consuming reports: new vendors, new flows, new subdomains are ongoing events, and the reports are your tripwire.
Timeouts worth noting: DNS TXT propagation is usually fast, but receiver-side caching means policy changes take up to 48 hours to be universally visible. Never follow a p=reject change with an immediate "why is mail bouncing" panic rollback — check reports first.
The failures that fill spam folders
In scan data and aggregate reports, the same handful of misconfigurations account for nearly all delivery pain:
- SPF over 10 lookups →
permerror→ mail treated as failing. The single most common cause of "we did everything and Gmail still bins us". - Two
v=spf1records (usually after adding a vendor "next to" the old record instead of editing it) → undefined behavior. - DKIM selector published but signer never configured, or the reverse — a
._domainkeyTXT that points at a key no message is signed with is a silent no-op, and flows you believe are signed are not. p=noneforever — monitoring without enforcement means phishing still renders in inboxes claiming your brand; only the reports know.- Missing alignment: SPF passes for
sendgrid.net,From:saysyourcompany.com, no DKIM signature from your domain → DMARC fails despite green SPF. The fix is a SendGrid-branded return-path with DKIM signing for your domain, not more SPF includes. - Subdomain wildcard catch-alls (
*.example.com TXT) that shadow the records a specific subdomain needs. DMARC'ssp=tag exists for exactly this; use it deliberately.
Frequently asked questions
Do SPF, DKIM and DMARC guarantee inbox placement?
No — they prove identity, and identity is table stakes. Gmail's bulk-sender requirements make them mandatory, but placement still depends on engagement, list hygiene and content. What they do guarantee: unsigned mail claiming to be you becomes visibly fake, and your signed mail is never mistaken for it.
Can I use DMARC with p=none and call it done?
You can, and it is better than nothing (you get visibility), but the phishing protection only arrives at quarantine/reject. Treat p=none as a phase, not a destination.
Do I need DKIM if SPF passes?
Yes. SPF alone fails the alignment test for any third-party sender, breaks whenever mail is forwarded, and carries no message-integrity guarantee. Every serious receiver expects DKIM.
How do I test without risking real mail?
Use Google's Postmaster Tools plus your rua reports in p=none, and send test messages through every flow (password reset, invoices, newsletters) to Gmail and Outlook accounts while watching the "show original" authentication results panel.
Where do I check what my domain currently publishes?
The free security scan fetches and validates your SPF, DKIM and DMARC records — including the 10-lookup limit and alignment pitfalls this guide describes — alongside seventeen other checks.
Remote Daemon