How-to DMARC

Set up DMARC, SPF, and DKIM

Walkthrough for publishing DMARC, SPF, and DKIM on a domain. Covers record syntax, common ESP setups, and verification.

30 to 60 min · DNS access required

TL;DR

  • 1Publish all three: SPF in DNS for authorized senders, DKIM CNAMEs (or TXT) per ESP, DMARC TXT at _dmarc with rua= reporting.
  • 2Start at p=none for at least 14 days, watch aggregate reports, then escalate to p=quarantine and finally p=reject.
  • 3Most common failures: SPF over 10 DNS lookups, an ESP signing with its own d= instead of yours, calendar invites going out unsigned.

What these three records do

SPF, DKIM, and DMARC are the three protocols receiving mail servers use to decide whether a message claiming to be from your domain is authentic. They work in layers: SPF lists which servers may send as you; DKIM cryptographically signs each outbound message so the receiver can verify it wasn't tampered with; DMARC publishes your policy for what to do when SPF and DKIM both fail, and asks receivers to report on every IP that sent as your domain.

Until all three are at enforcement (DMARC at p=reject), an attacker who picks up your domain in the visible From header can send convincing phishing mail to your customers, partners, and own employees. Major receivers like Gmail and Microsoft 365 default to delivering unauthenticated mail when no DMARC policy is published.

The records cost nothing (DNS edits, no infrastructure spend) but they are operationally non-trivial: every legitimate sender (marketing platform, transactional ESP, CRM, calendar path, shared inbox) has to be enrolled in SPF or DKIM before you can safely escalate the DMARC policy. Skipping that survey is how operators end up bouncing real customer mail.

How to publish them

  1. 1

    Inventory every outbound sender first. Marketing platform, transactional API, CRM, calendar invites, billing receipts. Each needs to be authorized in SPF or signing with DKIM whose d= aligns to your domain. The survey at p=none below will find what you missed, but that adds 1-2 weeks.

  2. 2

    Publish SPF. One TXT record on your apex starting v=spf1, listing include: chains per ESP (e.g. include:_spf.google.com), ending in ~all (soft fail). Cap total DNS lookups at 10 (see pitfalls).

  3. 3

    Enable DKIM in each ESP. Most ESPs (Google Workspace, Microsoft 365, SendGrid, Mailgun, Postmark, Resend, Mailchimp) publish either CNAME-delegated DKIM or a raw public-key TXT. Use the per-ESP admin UI; our DKIM generator outputs the exact record shape per provider.

  4. 4

    Publish DMARC at _dmarc.yourdomain with p=none. Include rua=mailto: with a mailbox or aggregator so receivers can send daily reports. Sample: v=DMARC1; p=none; pct=100; rua=mailto:dmarc@yourdomain.com; fo=1

  5. 5

    Watch aggregate reports for 14+ days. Each report shows per-IP volume and pass/fail counts. Fix any aligning failures (a legit ESP failing alignment usually means it's signing with its own d=; switch to CNAME-delegated DKIM so it signs with yours).

  6. 6

    Escalate to p=quarantine pct=10, then ramp. The full ramp is its own playbook; see the DMARC rollout playbook. Goal: p=reject pct=100 within 8-12 weeks of starting.

Common pitfalls

  • SPF over 10 DNS lookups. RFC 7208 caps SPF at 10 lookups; exceeding it triggers PermError and silently fails authentication. Each include: counts, and includes that contain includes count recursively. Use the SPF flattener or remove unused includes.

  • ESP signing with its own d=. If SendGrid or HubSpot signs your outbound with d=sendgrid.net, DKIM passes but does NOT align with your visible From, so DMARC fails. Enable CNAME-delegated DKIM in each ESP so they sign with your domain.

  • Forgetting calendar invites and shared mailboxes. Calendar invites from Workspace can go out signed by the user, not the org. Shared mailboxes route through different signing paths. Both bounce at p=reject if you didn't enroll them. Test both before escalating.

  • Jumping to p=reject in one step. Without 14+ days of p=none reports, you're guessing at which senders are aligned. Receivers cache the policy; bouncing real mail because of a missed ESP is expensive to roll back.

  • Multiple SPF records on one domain. Adding a second SPF TXT instead of editing the first is common (e.g. "add SendGrid"). RFC 7208 says receivers MUST treat that as PermError and the whole evaluation fails. There can be exactly one SPF record per domain.