SPF, DKIM, and DMARC: the 2026 setup guide
A concrete 2026 setup for email authentication — what Gmail and Yahoo now require, what's changed from 2024, and the DNS records you actually need.
Since Gmail and Yahoo's February 2024 bulk-sender requirements went into effect, "authentication is optional" stopped being a defensible position. In 2026 the bar rises further. Here's what you need live today if you send any meaningful volume to consumer mailboxes.
If you're setting this up to send through a vendor, our Transactional Email API configures SPF, DKIM rotation, and DMARC reporting alignment automatically — you'll still want to know what the records below actually do.
The three records, in one paragraph
SPF tells receivers which servers are authorized to send mail from your domain. DKIM lets receivers verify a message hasn't been tampered with and was really sent by you (or someone with your key). DMARC tells receivers what to do when SPF and DKIM don't align with the domain in the From: header — and where to send reports about it.
You need all three. SPF or DKIM alone isn't enough.
SPF — getting it right
Your SPF record is one TXT record at your apex. If you're new to TXT records in general, DNScale's primer on TXT records covers the format and common pitfalls.
yourapp.com. TXT "v=spf1 include:_spf.postscale.io ~all"
The ~all at the end is "soft fail" — receivers treat unauthorized senders as suspicious but don't outright reject. Move to -all (hard fail) once you're confident all your senders are included.
Gotchas:
- 10 DNS lookup limit. SPF resolves recursively.
include:,a,mx,ptr,exists, andredirectall count. Hit 11 and every receiver fails your SPF. Audit withdig +short txt yourapp.comand a tool like dmarcian's SPF surveyor. - One SPF record per domain. Not two. If you have
include:_spf.google.comfor Workspace andinclude:_spf.postscale.iofor transactional, they go in the same record:v=spf1 include:_spf.google.com include:_spf.postscale.io ~all - Subdomain vs apex.
spf1onmail.yourapp.comis separate fromyourapp.com. If you sendFrom: noreply@yourapp.com, the apex is what matters.
DKIM — what actually happens
DKIM signs outgoing messages with a private key. The corresponding public key sits in DNS under a selector:
<selector>._domainkey.yourapp.com. TXT "v=DKIM1; k=rsa; p=MIGfMA0G..."
With Postscale you don't generate keys — we rotate them and publish selectors automatically. You add two CNAMEs pointing at our key hosts (CNAME vs A records explained if you're deciding when to use each):
ps1._domainkey.yourapp.com. CNAME ps1._domainkey.postscale.io.
ps2._domainkey.yourapp.com. CNAME ps2._domainkey.postscale.io.
Two selectors means rotation doesn't interrupt delivery. We sign with one while the other is pre-published for the next rotation.
If you're manually managing keys, use RSA-2048 or Ed25519. Never publish a key shorter than 1024 bits — Gmail rejects messages signed with weaker keys. Rotate every 6–12 months.
DMARC — the 2026 settings
The minimum viable DMARC record:
_dmarc.yourapp.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourapp.com; fo=1"
Three fields to understand:
p=— policy.none= monitor only;quarantine= send suspicious mail to spam;reject= bounce at SMTP time.rua=— where to send aggregate reports. Required to do anything useful with DMARC.fo=1— send forensic-fail reports when any check fails (not just total failure). Useful during setup.
For 2026 you want to reach p=reject if you send to consumer mailboxes in any volume. Gmail has been sending visible "Unverified sender" warnings in Inbox for p=none senders since late 2024. Go straight to p=reject only after at least 30 days at p=none with clean aggregate reports.
See our separate post on parsing DMARC aggregate reports for the monitoring side.
The Gmail/Yahoo 2024 requirements (still apply)
For bulk senders (> 5,000 messages/day to Gmail users):
- SPF AND DKIM both pass. Not either.
- DMARC policy at least
p=nonewith validrua=. - One-click unsubscribe via
List-Unsubscribeheader with theList-Unsubscribe-Post: List-Unsubscribe=One-Clickheader. - Spam complaint rate < 0.3%. Sustained violation = throttled or blocked.
- PTR record for your sending IP matching the HELO name.
- TLS on SMTP. Not optional anymore.
Postscale configures 1, 5, 6 automatically. You need 2 (add the DMARC record), 3 (emit the right headers in your templates — our API does if you set the list_unsubscribe field), and 4 (keep your list clean).
What to set for a new domain in 2026
For a fresh domain sending transactional email:
; Apex SPF
yourapp.com. TXT "v=spf1 include:_spf.postscale.io ~all"
; DKIM (two selectors for rotation)
ps1._domainkey.yourapp.com. CNAME ps1._domainkey.postscale.io.
ps2._domainkey.yourapp.com. CNAME ps2._domainkey.postscale.io.
; DMARC
_dmarc.yourapp.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@yourapp.com; fo=1; pct=100"
; MTA-STS (optional but recommended)
_mta-sts.yourapp.com. TXT "v=STSv1; id=20260101"
Then send your first message and immediately do:
# Verify SPF, DKIM, DMARC all pass
swaks --to check-auth@verifier.port25.com \
--from you@yourapp.com \
--server smtp.postscale.io \
--auth LOGIN --auth-user YOUR_KEY
port25's responder emails back with a full authentication report. Shows pass/fail for every check.
Common failure modes
- DKIM signature includes headers that change in transit. Your signing policy should exclude
Received:andReturn-Path:— they're rewritten by relays. - From domain vs envelope domain mismatch. DMARC alignment requires the visible
From:domain to match either the DKIMd=domain or the SPFMAIL FROM. A common mistake is sendingFrom: hello@yourapp.combutMAIL FROM: bounces@sendgrid.net— no SPF alignment, DKIM has to cover. - Wildcard DNS hiding the problem. Some providers resolve
*.yourapp.comto an A record. Test withdig +short txt _dmarc.yourapp.comand confirm you get the TXT, not a web page IP. - DKIM key too long for DNS. Some DNS providers split a 2048-bit key into multiple strings. Joining them correctly requires quoted concatenation:
DNS clients concatenate the strings; if you forget the quotes the key is truncated and DKIM silently breaks."v=DKIM1; k=rsa; p=MIIBIj...ANBgkqhkiG9w0BAQEFAA" "OCAQ8AMIIBCgKCAQEAz..."
Next steps
- If you haven't set up DMARC yet, start today with
p=noneand a parsing service. You'll be atp=rejectwithin 45 days. - If you run SPF without DKIM, add DKIM. SPF breaks on forwarding; DKIM survives.
- If you have all three but don't parse reports, set up DMARC reporting — otherwise you have authentication without observability.
Further reading
- Postscale domain setup — the two-CNAME, five-minute version of everything above
- DNScale: Email security — SPF, DKIM, and DMARC from a DNS perspective — the DNS-layer companion to this post
- DNScale: TXT records explained
- DNScale: CNAME records explained