Guide 05 / 05 — Email
What are SPF, DKIM and DMARC?
How SPF, DKIM and DMARC stop people sending email in your name, what the DNS records look like, how alignment works, and how to roll out DMARC safely.
- Reading time
- 6 min
- Updated
- Topic
- Tool
- Email checker
Email was designed in the early 1980s without any way to check who sent a message. The protocol lets a server write any address into the From line, which is why “spoofed” email, with a bank or a CEO as the apparent sender, has been a problem for decades.
SPF, DKIM and DMARC are three DNS-based standards that fix this. Each one closes a different gap, and they only work properly together. You can see which of them a domain has published with the email checker, and how a received message fared against them with the email header analyzer.
Two “From” addresses
To understand these standards, you need to know that every email has two sender addresses:
| Also called | Who sees it | Used by | |
|---|---|---|---|
| Envelope sender | MAIL FROM, Return-Path, bounce address | Servers; appears in headers as Return-Path |
SPF |
| Header From | From, 5322.From | You, in your email app | DMARC (and humans) |
They don’t have to match. A newsletter from news@example.com is often sent with an envelope sender like bounces+123@mail.sendingservice.net so that bounces go to the email service. That is legitimate, but it also means a check on the envelope sender alone says nothing about the address you actually see. DMARC exists to close that gap.
SPF: which servers may send
Sender Policy Framework lets a domain publish the list of servers allowed to send mail using it as the envelope sender. It is a single TXT record at the domain itself:
example.com. TXT "v=spf1 ip4:203.0.113.10 include:_spf.google.com include:sendgrid.net -all"
This says: mail for example.com may come from 203.0.113.10, from Google Workspace’s servers and from SendGrid’s servers. Everything else should fail.
How to read an SPF record
| Part | Meaning |
|---|---|
v=spf1 |
Version tag, must come first |
ip4: / ip6: |
An address or range that may send, e.g. ip4:198.51.100.0/24 |
a / mx |
The servers in the domain’s own A or MX records may send |
include: |
Also allow whatever another domain’s SPF record allows (how email services are added) |
-all |
Everything else fails (strict) |
~all |
Everything else soft-fails: accept, but treat as suspicious |
?all |
Neutral, no opinion. Practically useless |
The receiving server checks the connecting IP address against this list and records spf=pass, fail, softfail, neutral, none or an error.
SPF pitfalls
- One record only. Two
v=spf1TXT records on the same domain is an error, and the result ispermerror. Merge them. - 10 DNS lookups maximum. Each
include,a,mx,existsandredirectcosts a lookup, including those nested inside includes. Go over the limit and SPF fails withpermerror. Large setups need to prune unused services. - Forwarding breaks SPF. When a message is forwarded, the forwarding server’s IP isn’t on your list. DKIM survives forwarding, which is one reason you need both.
- SPF ignores the visible From. It only checks the envelope sender.
DKIM: a signature on the message
DomainKeys Identified Mail adds a cryptographic signature to each message. The sending server signs selected headers and the body with a private key. The receiver fetches the matching public key from DNS and verifies that the message is unaltered and was signed by that domain.
The signature travels in a header:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s1;
h=from:to:subject:date:message-id; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB4nujc7YopdG5...
The important tags: d= is the signing domain, s= the selector, h= the headers that were signed, bh= a hash of the body and b= the signature itself.
The receiver combines the selector and domain to find the public key at <selector>._domainkey.<domain>:
s1._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
Selectors let a domain have several keys at once, one per sending service (Google Workspace, a newsletter tool, a helpdesk) and new ones during key rotation.
DKIM good practice
- Use 2048-bit RSA keys. 1024-bit keys still work but are considered weak.
- Configure DKIM with your own domain (
d=example.com) in every service that sends for you. Many services sign with their own domain by default, which passes DKIM but won’t help DMARC. - Rotate keys periodically by publishing a new selector, switching over, then removing the old one.
- Mailing lists that add footers or change subjects break the body or header hash. ARC (Authenticated Received Chain) is the mechanism lists and forwarders use to vouch for the original result.
DMARC: tying it to the From address
Domain-based Message Authentication, Reporting and Conformance does three things: it requires that SPF or DKIM pass for the domain you see in From, it tells receivers what to do if that fails, and it asks them to send you reports.
The record lives at _dmarc.<domain>:
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; adkim=r; aspf=r"
| Tag | Meaning |
|---|---|
p= |
Policy: none (monitor only), quarantine (send to spam), reject (refuse the message) |
sp= |
Policy for subdomains, if different |
rua= |
Where to send daily aggregate reports (XML) |
ruf= |
Where to send failure reports; few providers send these any more |
adkim= / aspf= |
Alignment mode: r relaxed (subdomains count, the default) or s strict (exact match) |
pct= |
Apply the policy to only a percentage of failing mail during rollout |
Alignment
A message passes DMARC if at least one of these is true:
- SPF passes and the envelope sender’s domain matches the From domain, or
- DKIM passes and the
d=signing domain matches the From domain.
With relaxed alignment, mail.example.com matches example.com. This is what makes the system work: a spoofer can pass SPF for their own server and sign DKIM with their own domain, but neither will align with paypal.com in the From line.
Reading the results in a message
Receiving servers record what they found in the Authentication-Results header:
Authentication-Results: mx.google.com;
dkim=pass header.i=@example.com header.s=s1 header.b=AuUoFEfD;
spf=pass (google.com: domain of bounce@mail.example.com designates 203.0.113.10 as permitted sender) smtp.mailfrom=bounce@mail.example.com;
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=example.com
Here all three pass, SPF and DKIM both align with example.com (SPF through the relaxed match on mail.example.com), and the domain’s policy is quarantine. Paste any message’s headers into the email header analyzer to get this broken down without reading raw text.
Rolling out DMARC without losing mail
Jumping straight to p=reject is the classic way to block your own invoices. A safer path:
- Inventory senders. List every service that sends as your domain: office email, CRM, newsletter, billing, helpdesk, website forms.
- Publish SPF and enable DKIM with your own domain in each of them.
- Publish
p=nonewithrua=. Read the aggregate reports for two to four weeks (a free report viewer helps) and fix any legitimate source that fails. - Move to
p=quarantine, optionally withpct=to start small. - Move to
p=rejectonce reports show only spoofed mail failing. - Keep monitoring. New tools get added; each one needs SPF or DKIM set up before it goes live.
Why it matters now
Since February 2024, Gmail and Yahoo require anyone sending more than about 5,000 messages a day to their users to have SPF, DKIM and a DMARC record (at least p=none), with the From domain aligned, plus one-click unsubscribe for marketing mail. Microsoft introduced similar rules for Outlook.com in 2025. Smaller senders aren’t formally bound, but missing authentication is one of the most common reasons legitimate mail lands in spam.
What these standards don’t do
They verify the domain, not the intent. A scammer who registers examp1e-billing.com can publish perfect SPF, DKIM and DMARC records. That is why the phishing checklist still starts with reading the sender’s domain, and why the email checker also looks at domain age and look-alike names.
Summary
| Checks | Record location | Survives forwarding | |
|---|---|---|---|
| SPF | The sending server’s IP is authorised for the envelope domain | TXT at example.com |
No |
| DKIM | The message is signed by a domain and unchanged | TXT at selector._domainkey.example.com |
Usually, unless modified |
| DMARC | SPF or DKIM passes for the From domain; sets policy and reports | TXT at _dmarc.example.com |
Via DKIM |
Last updated 1,250 wordsSpotted a mistake? Tell us