SPF, DKIM and DMARC for Cold Email: The Complete Setup Guide
Authentication is the entry ticket. Since Google and Yahoo's sender requirements, mail without SPF, DKIM and DMARC doesn't get a fair hearing — it gets filtered before your copy is ever judged. Here's the exact setup I deploy across every sending domain I manage.
SPF — who is allowed to send
SPF is a TXT record listing the servers permitted to send for your domain. One record per domain, max 10 DNS lookups.
Google Workspace: v=spf1 include:_spf.google.com ~all
Microsoft 365: v=spf1 include:spf.protection.outlook.com ~all
Common failures: two SPF records on one domain (instantly invalid), leftover includes from old tools blowing the 10-lookup limit, and +all (which authorizes the entire internet).
DKIM — cryptographic proof it wasn't altered
DKIM signs each message with a private key; receivers verify against the public key in your DNS. The critical detail: publishing the DNS record is only half the job — you must also enable signing in Google Admin (Apps → Gmail → Authenticate email) or via M365. I've audited fleets where most domains had the record but signing was never switched on. Verify by sending a real message and checking headers for dkim=pass with your domain, not the provider's default.
DMARC — the policy that ties it together
DMARC tells receivers what to do when SPF/DKIM fail, and requires alignment — the authenticated domain must match your From domain.
Publish at p=none
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com — observe, don't enforce.
Watch reports 1–2 wks
Confirm your real mail passes aligned SPF/DKIM and nothing legitimate fails.
Move to p=quarantine
Failures go to spam instead of inbox. This is the standard for cold email fleets.
Verify per domain
Run the panel above on every domain — automation helps at fleet scale.
The order to build a new domain
On a fresh sending domain: MX first, then SPF, then create the mailboxes, enable DKIM and confirm signing, then DMARC at p=none, then redirects and tracking domain, then warmup. Doing DMARC-at-quarantine before DKIM signing is live is a classic self-inflicted spam trip. Full domain buildout: domain setup guide; what happens when this is wrong: why cold emails go to spam.
Two follow-ons worth reading: if SPF and DKIM pass but DMARC does not, the cause is alignment — why DMARC fails when SPF and DKIM pass. And for what the mailbox providers actually require of you, is DMARC mandatory?
Alignment: the part that fails after everything passes
SPF passing and DKIM passing is not DMARC passing. DMARC asks a second question of each: does the domain that passed match the domain in the visible From header? SPF is checked against the envelope sender (the Return-Path), which on Google Workspace and Microsoft 365 is your domain, so SPF aligns. On many third-party senders the Return-Path is theirs, so SPF passes for their domain and does not align with yours. DKIM is checked against the d= in the signature; if the signing domain is yours, it aligns.
For cold email through Workspace or M365 this mostly takes care of itself. It breaks in two places: a sending tool that relays through its own servers and signs with its own domain, and a tracking or forwarding setup that rewrites the envelope. The symptom is DMARC reports showing failures on mail you know you sent. The alignment checker takes a raw message and shows which of the two identifiers aligned and which did not; the alignment post goes through every case.
The mistakes I fix most often
Two SPF records. A second v=spf1 TXT record — usually left behind by a website builder or a previous provider — makes SPF a permanent error on every check. There must be exactly one; merge them. The SPF merger does it without breaking either.
SPF over ten lookups. Every include:, a, mx and redirect= costs a DNS lookup and the limit is ten. Google is 1, Microsoft is 1, and then a CRM, a helpdesk and a marketing tool later the record is at 11 and silently returning permerror. The lookup counter shows the tree; the flattening guide is the fix when you cannot drop an include.
DKIM key never turned on. Publishing the CNAME is half the job. Workspace needs "Start authentication" clicked in the admin console after the record resolves; Microsoft needs the DKIM signing enabled per domain in the Defender portal. Until then the record exists and nothing is signed. The DKIM checker confirms the key resolves; only a real sent message confirms it is being used.
DMARC at p=none forever. Monitoring mode is a starting point, not a policy. Google and Microsoft treat p=none as "has DMARC" for the bulk-sender rules, but an enforcing policy is a positive reputation signal and the only thing that stops spoofing of your domain. Two weeks of clean reports, then p=quarantine, then p=reject. The step-by-step is written for exactly this.
No rua address. A DMARC record without a reporting address tells you nothing. Add one before anything else, and use a parser — reports are XML and unreadable raw. The report parser turns them into a table of sources and results.
Verifying a domain end to end
Records resolve
Run the domain checker. SPF, DKIM selector and DMARC should all show green; MX should be the provider's, not a parked host.
A real message passes
Send from the mailbox to a Gmail address you control, open the original, and read the Authentication-Results header. The header analyzer decodes it. All three should say pass, and DKIM should show your domain.
Reports arrive
Within 24–48 hours the first aggregate report lands at your rua address. Parse it. Every source it lists should be one you recognise.
Bulk-sender check
The bulk sender checker runs the domain against Google's and Yahoo's published requirements — authentication, alignment, PTR, TLS, List-Unsubscribe — in one pass.
For a fleet, run step one across the whole list at once — the Workspace / M365 DNS checker compares every domain against what the provider expects — and the email DNS setup tool generates and applies the full record set for new domains so steps one to three are the same on every one.
Sources
- Google Workspace — Turn on DKIM signing
- Google — Email sender guidelines
- Microsoft Learn — Configure DKIM
- Microsoft Learn — Configure DMARC
- Yahoo — Sender best practices
- RFC 7208 — SPF
- RFC 9989 — DMARC
Tools for this
DMARC alignment checkerWhy DMARC passed or failed, from headers.SPF mergerTwo SPF records into one valid one.SPF lookup counterCount DNS lookups against the limit of ten.DKIM checkerFind signing keys without the selector.Frequently asked questions
What DMARC policy should cold email domains use?
Start every new sending domain at p=none with a rua reporting address so you can see alignment before enforcing. Once SPF and DKIM pass consistently for a couple of weeks, move to p=quarantine. Publishing no DMARC at all now costs you placement under Google and Yahoo bulk-sender requirements.
Do I need SPF, DKIM and DMARC on every sending domain?
Yes — every single one. Authentication is per-domain, not per-account. A fleet where 90% of domains are authenticated and 10% are not still bleeds: the broken 10% get junked and drag down the campaign stats you make decisions with.
Why does DKIM show as configured but fail?
Usually the CNAME or TXT record was published in DNS but DKIM signing was never turned on inside Google Admin or Microsoft 365 — the record existing does not mean the mailbox is signing. Always confirm by inspecting the headers of a real sent message.
Do I need DMARC if I only send cold email through Google Workspace?
Yes. Since February 2024 Gmail and Yahoo require a DMARC record on any domain sending 5,000 or more messages a day to them, and Microsoft added the same rule for Outlook.com in 2025. Below that threshold it is not mandatory, but a domain with no DMARC is one that any receiver can be spoofed from, and an enforcing DMARC policy is a reputation signal on its own. Publish it on every sending domain regardless of volume.
What is the difference between DKIM 1024 and 2048-bit keys?
Key length. 1024-bit keys are still accepted but Google recommends 2048 and treats the shorter key as weaker. Workspace generates 2048 by default now; older tenants and some third-party tools still issue 1024. If a domain's DKIM record was created more than a couple of years ago, regenerate it at 2048 and rotate the selector.
How often should I re-check SPF, DKIM and DMARC on a sending fleet?
Weekly, automated. Records drift: a provider rotates a DKIM selector, someone adds an include, a zone gets re-imported without the TXT records. On a fleet the drift is invisible until placement drops. The domain monitor checks every domain daily and flags the change the morning it happens.