SPF, DKIM and DMARC are DNS records that let receiving mail servers check that an email claiming to be from your domain really is. Without them, your mail is more likely to land in spam, and anyone can forge your address. Large mailbox providers now require them for anyone sending in volume.
| Record | Answers the question | Where it lives |
|---|---|---|
| SPF | Which servers may send mail for this domain? | TXT on the domain |
| DKIM | Was this message signed by the domain, and is it unchanged? | TXT on selector._domainkey |
| DMARC | What should receivers do when checks fail, and who gets reports? | TXT on _dmarc |
1. SPF
List every service that sends mail as your domain: your mailbox provider, your website’s mail, newsletter tools, helpdesks. Each provider documents the include: value to add. Then publish one TXT record on the bare domain:
v=spf1 include:_spf.mailprovider.example include:newsletter.example -all
- Only one SPF record is allowed. Two records make SPF fail entirely; merge them into one.
-allmeans “reject everything else”.~all(softfail) is gentler while you test.- SPF allows at most 10 DNS lookups; every
include:counts.
SPF values for common providers
| Provider | Add to your SPF record |
|---|---|
| Google Workspace | include:_spf.google.com |
| Microsoft 365 | include:spf.protection.outlook.com |
| Your own server | ip4:203.0.113.25 or mx, if it is also your MX |
| Newsletter and transactional services | The include: from their setup page |
A domain that uses Google Workspace and one newsletter service would publish:
v=spf1 include:_spf.google.com include:servers.newsletter.example -all
Always copy the exact values from each provider’s own instructions, as they occasionally change.
2. DKIM
DKIM signs each message with a private key; the public key goes in DNS. Your mail provider generates the key pair and gives you a record to add, something like:
Name: selector1._domainkey
Type: TXT (or CNAME, if the provider asks)
Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqh...
Turn on signing in the provider’s settings after the record is live. Each sending service has its own selector and record.
3. DMARC
Start in monitoring mode so nothing is blocked while you check results:
Name: _dmarc
Type: TXT
Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com
Receivers send daily reports to that address, showing which servers sent mail as you and whether they passed. After a few weeks of clean reports, tighten the policy to p=quarantine, then p=reject.
The DMARC tags you need
| Tag | Meaning | Example |
|---|---|---|
p | Policy for failing mail: none, quarantine or reject | p=quarantine |
rua | Where to send daily summary reports | rua=mailto:dmarc@example.com |
pct | Share of failing mail the policy applies to, for gradual roll-out | pct=25 |
sp | Policy for subdomains, if different | sp=reject |
adkim, aspf | Alignment strictness: r relaxed (default) or s strict | adkim=s |
Alignment: the part people miss
DMARC does not just check that SPF or DKIM passed. It checks they passed for your domain. A newsletter service may pass SPF for its own domain while sending “from” yours; that does not count. For DMARC to pass, at least one of these must be true:
- SPF passed, and the domain in the hidden envelope sender (the
Return-Path) matches your From domain. - DKIM passed, and the signing domain (
d=in the signature) matches your From domain.
In practice, setting up DKIM with your own domain at every sending service is the reliable way to pass, because SPF often breaks when mail is forwarded. Look for “custom domain authentication” or “domain signing” in each service’s settings.
Reading the reports
DMARC reports arrive as zipped XML files, one per receiving provider per day. Free and paid report readers turn them into a readable list of every server sending as your domain, with pass and fail counts. Look for:
- Your known services failing: their SPF include or DKIM is not set up yet. Fix before tightening the policy.
- Unknown servers passing: something you forgot, such as a CRM or invoicing tool. Add it properly.
- Unknown servers failing: often spoofing attempts. These are what
p=rejectwill block.
Check your work
dig TXT example.com +short
dig TXT _dmarc.example.com +short
dig TXT selector1._domainkey.example.com +short
Then send a message to a mailbox you control and view the original headers. Look for spf=pass, dkim=pass and dmarc=pass in the Authentication-Results line.
Forwarding and mailing lists
When a message is forwarded, for example from an old address to Gmail, it arrives from the forwarding server, which is not in your SPF record, so SPF fails. DKIM usually survives forwarding as long as the message is not changed. Mailing lists that add footers or change subject lines break DKIM too. This is why moving to p=reject needs a few weeks of reports first, and why DKIM matters more than SPF.
A domain that never sends email should still say so: publish v=spf1 -all and a DMARC record with p=reject. That stops it being used for spoofing.
Related
Something out of date? Software changes. If a step no longer works, tell us and we will check it and update the page.
