Set Up DMARC, SPF & DKIM
When a lookalike domain has MX records, attackers can send emails that appear to come from your domain. SPF, DKIM, and DMARC work together to tell receiving mail servers to reject those emails. This guide walks you through setting up all three from scratch, with exact DNS records and verification steps.
Estimated time: 30–60 minutes · Requires access to your DNS provider
How SPF, DKIM, and DMARC Work Together
SPF (Sender Policy Framework): A DNS TXT record that lists which IP addresses and mail servers are authorized to send email on behalf of your domain. When an email arrives, the receiving server checks whether the sending server's IP matches your SPF record. Defined in RFC 7208.
DKIM (DomainKeys Identified Mail): A cryptographic signature added to outgoing emails. Your mail server signs each message with a private key, and a corresponding public key is published in DNS. The receiving server uses the public key to verify the signature, confirming the message was not altered in transit. Defined in RFC 6376.
DMARC (Domain-based Message Authentication, Reporting & Conformance): A policy layer that sits on top of SPF and DKIM. It tells receiving servers what to do when authentication fails (nothing, quarantine, or reject), and where to send aggregate and forensic reports so you can monitor who is sending email as your domain. Defined in RFC 7489.
The authentication flow:
- An email arrives at the receiving server claiming to be from
you@yourdomain.com. - The server checks SPF: Is the sending IP authorized by
yourdomain.com's SPF record? - The server checks DKIM: Does the DKIM signature validate against the public key in DNS?
- The server checks DMARC: Did either SPF or DKIM pass and align with the From domain?
- Based on the DMARC policy (
p=none,p=quarantine, orp=reject), the server delivers, quarantines, or rejects the message.
From: header aligns with the domain authenticated by SPF or DKIM. This prevents attackers from passing SPF with their own domain while spoofing yours in the From header. Alignment can be relaxed (subdomains match the parent) or strict (exact match only).
1 Check Your Current State
Before making any changes, audit what you already have. Run these commands from your terminal (macOS, Linux, or WSL on Windows):
Check SPF record
You should see a single TXT record starting with v=spf1. If you see nothing, you have no SPF record.
Check DKIM record
Common selectors: google (Google Workspace), selector1 / selector2 (Microsoft 365), resend (Resend), s1 / s2 (Mailgun).
Check DMARC record
You should see a TXT record starting with v=DMARC1. If nothing appears, you have no DMARC policy.
Check MX records (which servers receive your mail)
Online tools (no terminal needed):
- MXToolbox SuperTool. Enter your domain, choose SPF/DKIM/DMARC lookup
- MXToolbox Email Health: Full visual report of all email authentication
- Google Admin Toolbox Check MX: Google's free DNS diagnostic tool
- dmarcian DMARC Inspector: Detailed DMARC record analysis
- mail-tester.com: Send an email to their address and get a deliverability score
2 Add or Update Your SPF Record
In your DNS provider, add (or update) a TXT record on your root domain (@). The value must start with v=spf1 and end with an all mechanism.
SPF record syntax:
Mechanisms (how to authorize senders):
include:domain.com: Authorize all IPs allowed by another domain's SPFip4:203.0.113.0/24: Authorize a specific IPv4 address or rangeip6:2001:db8::/32: Authorize a specific IPv6 address or rangea: Authorize the IP(s) your domain's A record points tomx: Authorize the IP(s) of your domain's MX servers
Qualifiers (what to do with non-matching senders):
-all: Hard fail, reject anything not explicitly authorized (recommended for production)~all: Soft fail, accept but mark as suspicious (good while testing)?all: Neutral, no opinion (not recommended)+all: Pass all, allow everything (never use this, it defeats the purpose)
SPF records by provider
Google Workspace only:
Microsoft 365 only:
Resend only:
SendGrid only:
Mailgun only:
Google Workspace + Resend + SendGrid (combined):
Critical SPF rules:
- One record only. You can only have one SPF TXT record per domain. Multiple SPF records cause both to fail. Combine all providers into a single record.
- 10 DNS lookup limit. Each
include:,a,mx, andredirectmechanism costs one DNS lookup. Nested includes count too. Exceeding 10 causes a permanent fail (permerror). Useip4:andip6:mechanisms (which don't count as lookups) to stay under the limit. - Character limit. A single DNS TXT record can be up to 255 characters per string. For longer SPF records, your DNS provider will automatically split them into multiple strings within one record.
- Start with
~all, move to-all. Use soft fail while testing, then switch to hard fail once you have confirmed all legitimate sending sources are included.
3 Enable DKIM Signing
DKIM requires two things: your email provider generates a key pair and signs outgoing messages, and you publish the public key as a DNS record so receivers can verify the signature.
DKIM DNS record format:
The selector is a label chosen by your provider (e.g., google, selector1, resend). The p= value is the base64-encoded public key.
Google Workspace
- Go to Google Admin Console → Apps → Google Workspace → Gmail
- Click Authenticate email
- Select your domain and click Generate new record
- Choose a DKIM key bit length (2048-bit recommended)
- Copy the generated TXT record value
- In your DNS provider, create a TXT record:
Name: google._domainkeyType: TXTValue: v=DKIM1; k=rsa; p=MIGfMA0GCSqG... (paste from Google)
- Wait for DNS propagation (up to 48 hours, usually faster)
- Return to the Admin Console and click Start authentication
Microsoft 365
- Go to Microsoft 365 Defender portal → Email & collaboration → Policies & rules → Threat policies → Email authentication settings → DKIM
- Select your domain and click Enable
- Microsoft will display two CNAME records to add to your DNS:
Name: selector1._domainkeyType: CNAMEValue: selector1-yourdomain-com._domainkey.yourtenant.onmicrosoft.comName: selector2._domainkeyType: CNAMEValue: selector2-yourdomain-com._domainkey.yourtenant.onmicrosoft.com
- Add both CNAME records to your DNS provider
- Return to the Defender portal and enable DKIM signing
Resend
- Go to Resend Dashboard → Domains → Add Domain
- Resend will provide DNS records to add, including DKIM records (typically CNAME records pointing to Resend's DKIM infrastructure)
- Add all provided DNS records to your DNS provider
- Click Verify in the Resend dashboard
SendGrid
- Go to Settings → Sender Authentication → Authenticate Your Domain
- Select your DNS provider and enter your domain
- SendGrid will provide three CNAME records (two for DKIM, one for SPF branding)
- Add all CNAME records to your DNS provider
- Click Verify in the SendGrid dashboard
Mailgun
- Go to Sending → Domains → Add New Domain
- Mailgun will display TXT records for DKIM (typically using selectors like
smtp._domainkeyorpic._domainkey) - Add the provided TXT records to your DNS provider
- Click Verify DNS Settings in the Mailgun dashboard
Verify DKIM is working:
You should see a response containing v=DKIM1; k=rsa; p=.... If using CNAME records (Microsoft 365, SendGrid), the CNAME will resolve to the provider's TXT record automatically.
4 Add a DMARC Record
Add a TXT record with the name _dmarc (or _dmarc.yourdomain.com depending on your DNS provider). DMARC should be rolled out gradually: start in monitor mode, review reports, then tighten the policy.
DMARC record tags reference:
| Tag | Required | Description |
|---|---|---|
| v=DMARC1 | Yes | Protocol version (must be first) |
| p= | Yes | Policy: none (monitor), quarantine (spam folder), reject (block) |
| rua= | No* | Aggregate report recipients (comma-separated mailto: URIs). *Strongly recommended. |
| ruf= | No | Forensic (failure) report recipients. Not all providers send these. |
| pct= | No | Percentage of messages the policy applies to (1-100, default 100) |
| adkim= | No | DKIM alignment: r (relaxed, default) or s (strict) |
| aspf= | No | SPF alignment: r (relaxed, default) or s (strict) |
| sp= | No | Subdomain policy (same values as p=). Defaults to parent domain policy. |
| fo= | No | Forensic report options: 0 (both fail, default), 1 (either fails), d (DKIM fails), s (SPF fails) |
| ri= | No | Report interval in seconds (default 86400 = 24 hours) |
Monitor mode (weeks 1-4)
Collects reports without affecting mail delivery. Use this phase to identify all legitimate sending sources.
Quarantine at 25% (weeks 5-6)
Start quarantining a portion of failing mail. Monitor reports for false positives.
Quarantine at 100% (weeks 7-8)
All failing mail goes to spam. Continue monitoring.
Reject (week 9+, strongest protection)
All failing mail is rejected outright. This is the goal state for maximum brand protection.
Reading DMARC aggregate reports:
The rua address will receive daily XML reports from mail providers (Gmail, Outlook, Yahoo, etc.). These reports contain data about who is sending email as your domain and whether SPF/DKIM passed. Raw XML is hard to read, so use a free tool to parse them:
- Postmark DMARC Digests: Free weekly summaries in plain English
- dmarcian: Free tier for low-volume domains, detailed dashboards
- MXToolbox DMARC Report Analyzer: Upload XML reports for analysis
- Report URI: Free tier available, auto-processes incoming reports
rua address is on a different domain than the one being monitored (e.g., reports for example.com going to dmarc@otherdomain.com), the receiving domain must publish a special DNS record to authorize it:
5 Verify Everything Is Working
After DNS propagates (usually within minutes, up to 48 hours in rare cases), verify all three are configured correctly.
Method 1: Send a test email
- Go to mail-tester.com and copy the test email address
- Send an email from your domain to that address
- Click "Then check your score". A score of 10/10 means SPF, DKIM, and DMARC all pass
Method 2: Check email headers
- Send an email from your domain to a Gmail address
- Open the email in Gmail, click the three dots menu, and select Show original
- Look for these headers at the top:
SPF: PASSDKIM: PASSDMARC: PASS
Method 3: Command-line verification
6 Protect Subdomains
Attackers often target subdomains that do not send email (e.g., blog.yourdomain.com, cdn.yourdomain.com). Protect them even if they never send mail.
Null SPF for non-sending subdomains:
This tells receivers "no server is authorized to send email for this subdomain."
DMARC subdomain policy (set in your root DMARC record):
The sp=reject tag applies the reject policy to all subdomains.
Null MX for non-email subdomains (optional but thorough):
A null MX record explicitly states this subdomain does not accept email.
7 Troubleshooting Common Issues
SPF PermError: Too many DNS lookups
SPF allows a maximum of 10 DNS lookups per evaluation. Each include:, a, mx, and redirect counts as one lookup, and nested includes count too.
Fix:
- Replace
include:withip4:orip6:ranges where possible (these do not count as lookups) - Remove unused includes (old providers you no longer use)
- Use an SPF flattening service (e.g., AutoSPF) to resolve includes into IP addresses
- Check your lookup count: MXToolbox SPF Lookup
Multiple SPF records found
Your domain has more than one TXT record starting with v=spf1. The SPF specification requires exactly one SPF record per domain. Multiple records cause a PermError and both are ignored.
Fix:
- Merge all SPF records into a single TXT record
- Delete the duplicate records from your DNS provider
DKIM signature does not verify
The DKIM signature in the email header does not match the public key in DNS.
Fix:
- Confirm the DNS record name matches the selector in the email header (check the
s=tag in the DKIM-Signature header) - Make sure you copied the full public key without truncation or extra spaces
- If using CNAME records (Microsoft 365, SendGrid), verify the CNAME resolves correctly:
dig CNAME selector1._domainkey.yourdomain.com - Some DNS providers silently truncate long TXT records, so verify the full value is stored
- Regenerate the DKIM keys in your provider's dashboard and update DNS
DMARC reports show legitimate emails failing
You see SPF or DKIM failures for emails you actually sent (forwarded messages, mailing lists, third-party services).
Fix:
- Forwarded mail failing SPF: This is expected. When mail is forwarded, the sending IP changes. DKIM should still pass because the signature travels with the message. This is why having both SPF and DKIM is important, since DMARC passes if either one passes with alignment.
- Third-party service failing both: Add the service's SPF include to your record and set up DKIM signing in their dashboard.
- Mailing lists (e.g., Google Groups, Mailman): Mailing lists often rewrite the From header. Consider using relaxed alignment (
adkim=r; aspf=r), which is the default. - Before moving to p=reject: Stay on
p=noneorp=quarantineuntil your reports show near-zero legitimate failures.
DMARC record not found
Your DMARC TXT record exists in your DNS provider but does not appear in lookups.
Fix:
- Verify the record name is exactly
_dmarc(some providers need_dmarc.yourdomain.com, others just_dmarc) - Confirm the record type is TXT (not CNAME or other)
- Check for a leading/trailing space in the record value
- Wait for DNS propagation, then use
dig +trace TXT _dmarc.yourdomain.comto check authoritative servers directly
Emails going to spam despite passing authentication
SPF, DKIM, and DMARC all pass, but emails still land in spam.
Fix:
- Authentication alone does not guarantee inbox delivery. Spam filters also consider content, sender reputation, engagement metrics, and other signals.
- Check your domain/IP reputation at Google Postmaster Tools
- Avoid spammy content patterns (all caps, excessive links, misleading subjects)
- Confirm you have proper unsubscribe headers for marketing email (required by Gmail and Yahoo as of February 2024)
Free Tools for Ongoing Monitoring
| Tool | What it does |
|---|---|
| MXToolbox | SPF, DKIM, DMARC lookups; blacklist check; email health report |
| dmarcian | DMARC record inspector; free report processing tier |
| Google Admin Toolbox | Check MX, SPF, DKIM for any domain; dig/traceroute tools |
| Postmark DMARC | Free weekly DMARC report summaries in plain English |
| mail-tester.com | Send a test email, get a deliverability score with SPF/DKIM/DMARC results |
| Google Postmaster Tools | Domain reputation, spam rate, authentication rates for Gmail |
| Learn DMARC | Interactive tool that shows SPF/DKIM/DMARC checks in real time |
Quick Reference Checklist
-
☐
Audit current SPF, DKIM, and DMARC records with
digor MXToolbox - ☐ Create or update a single SPF TXT record on your root domain with all authorized senders
- ☐ Enable DKIM in each email provider's dashboard and publish the DNS records
-
☐
Add a DMARC record starting with
p=noneand aruaaddress - ☐ Send a test email to mail-tester.com and confirm SPF, DKIM, DMARC all pass
- ☐ Monitor DMARC reports for 2-4 weeks
-
☐
Progress to
p=quarantine, thenp=reject -
☐
Add null SPF records (
v=spf1 -all) on non-sending subdomains -
☐
Switch SPF from
~allto-allonce everything is confirmed working