Why this got urgent
Since February 2024 Gmail and Yahoo want every sender to authenticate their mail, and anyone sending in bulk to also publish DMARC and keep complaints low. A shop sends two quite different kinds of mail from the same domain. One is transactional (order confirmations, password resets, shipping notices). The other is marketing. Both suffer when the domain's setup is incomplete, and it's the transactional mail customers actually need.
The three records
| Record | What it checks | Where it lives |
|---|---|---|
| SPF | Is this IP address allowed to send for the envelope sender's domain? | TXT on the domain |
| DKIM | Was the message signed with a key published for the signing domain? | TXT on selector._domainkey |
| DMARC | Did SPF or DKIM pass for the domain in the From line the customer sees? And what to do if not | TXT on _dmarc |
The word that trips people up is alignment. SPF checks the envelope sender (the Return-Path). DKIM checks the d= domain in the signature. On its own, neither says anything about the From address on screen. DMARC only passes if at least one of them passes and its domain matches the From domain. In strict mode the match has to be exact. In relaxed mode the same parent domain is enough.
The classic failure: campaigns go out through a mail platform and pass SPF and DKIM for the platform's domain. Both checks pass. Neither matches your From domain. DMARC fails.
List everything that sends as you
Go through every system that sends mail with your domain in the From line:
- The mailbox provider (Google Workspace, Microsoft 365).
- The shop itself, through PHP mail or an SMTP relay.
- The campaign tool (Brevo, or similar).
- Invoicing, the helpdesk, the ERP.
- Monitoring and backup notifications, which everybody forgets.
Each of them needs its own DKIM key on your domain, and either a place in SPF or, better, its own subdomain.
The records themselves
example.com. TXT "v=spf1 include:_spf.google.com include:spf.brevo.com -all"
google._domainkey TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
brevo1._domainkey CNAME b1.example-com.dkim.brevo.com.
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; adkim=r; aspf=r"
The include names and DKIM selectors above are examples. Use exactly what each platform gives you for your account. SPF also allows no more than ten DNS lookups while it's being evaluated. Every include counts, includes inside includes count as well, and going over the limit makes SPF return permerror, which fails the same way a wrong record does.
Keep marketing on its own subdomain
If campaigns go out from something like news.example.com, their reputation, complaints and unsubscribes stay separate from the order mail on example.com. Each subdomain gets its own SPF and DKIM, and its own DMARC policy if needed (through the sp= tag or a separate record).
From p=none to p=reject, slowly
- Watch. Publish
p=nonewith anruaaddress and collect the daily reports for two to four weeks. They list every server that sent mail as your domain, and whether it passed. - Fix. Every legitimate sender has to pass with alignment. Anything you don't recognise is either a forgotten system or someone pretending to be you.
- Quarantine. Move to
p=quarantine, perhaps withpct=25at first, and keep reading the reports. - Reject. Once the reports only show your own aligned mail, move to
p=reject.
For campaign mail
The 2024 rules also ask for one-click unsubscribe, as defined in RFC 8058. It takes two headers:
List-Unsubscribe: <https://news.example.com/u/abc123>, <mailto:unsub@news.example.com?subject=abc123>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
Campaign platforms add these for you. Home-made newsletter scripts usually don't. And keep an eye on the spam rate in Google Postmaster Tools: the hard limit is 0.3%, but delivery starts getting worse well before that, somewhere above 0.1%.