domain-setup-spf-dkim-dmarc
SPF, DKIM, DMARC Setup
SPF, DKIM, and DMARC are DNS records that authenticate your sending domain. Without them, receiving mail servers treat your emails as unverified and route them to spam. With them, you prove to Google, Microsoft, and every other mail provider that emails from your domain are legitimate. These three records are the foundation of email deliverability. Nothing else matters until they're correct.
The principle: set up all three before sending a single cold email. Not after. Not "when we start having deliverability problems." Before the first send. Fixing authentication after your domain has already been flagged as spam is 10x harder than setting it up correctly from day one.
The Three Records Explained
| Record | What it does | Analogy |
|---|---|---|
| SPF | Lists which mail servers are allowed to send email from your domain | A bouncer with a guest list. "Only these servers can send as @yourdomain.com" |
| DKIM | Adds a digital signature to every email proving it wasn't tampered with | A wax seal on a letter. The recipient verifies the seal matches your public key |
| DMARC | Tells receiving servers what to do with emails that fail SPF or DKIM | The policy enforcement. "If SPF or DKIM fails, reject the email (or quarantine it, or do nothing)" |
Why all three are required
| Without SPF | Anyone can send email pretending to be from your domain. Spam filters flag you |
|---|---|
| Without DKIM | Emails can be modified in transit. Receiving servers can't verify integrity |
| Without DMARC | Even if SPF and DKIM pass, there's no policy telling servers what to do with failures. And you get no reporting on authentication results |
All three are required for cold outbound. Google and Microsoft require SPF and DKIM alignment. DMARC is technically optional but practically required for consistent inbox placement. Set up all three.
SPF (Sender Policy Framework)
What SPF does
SPF is a TXT record on your domain's DNS that lists every server authorized to send email on your behalf. When a receiving server gets an email from your domain, it checks the SPF record: "Is this sending server on the approved list?"
How to set it up
Step 1: Identify all services that send email from your domain
| Service | Why it sends email | Example include |
|---|---|---|
| Google Workspace | Team email (you@company.com) | include:_spf.google.com |
| Microsoft 365 | Team email | include:spf.protection.outlook.com |
| HubSpot | Marketing email, sequences | include:mail.hubspot.net |
| Lemlist | Cold outbound sequences | include:_spf.lemlist.com |
| Outreach | Cold outbound sequences | include:_spf.outreach.io |
| Salesloft | Cold outbound sequences | include:salesloft.com |
| Apollo | Cold outbound sequences | include:_spf.apollo.io |
| Instantly | Cold outbound sequences | include:_spf.instantly.ai |
| Smartlead | Cold outbound sequences | include:_spf.smartlead.ai |
| SendGrid | Transactional email | include:sendgrid.net |
| Mailgun | Transactional email | include:mailgun.org |
| Postmark | Transactional email | include:spf.mtasv.net |
Step 2: Create the SPF record
Add a single TXT record to your domain's DNS:
Type: TXT
Host: @ (or blank, depending on DNS provider)
Value: v=spf1 include:_spf.google.com include:mail.hubspot.net include:_spf.lemlist.com ~all
Replace the includes with your actual sending services.
SPF rules
- One SPF record per domain. Never create two SPF TXT records. If you need multiple includes, put them all in one record. Two SPF records = both are invalid
- Maximum 10 DNS lookups. Each
include:counts as one lookup. Nested includes (an include that includes another) also count. If you exceed 10, SPF fails permanently. Check your lookup count with a tool like MXToolbox - Use
~all(softfail) during setup. Switch to-all(hardfail) after confirming everything works.~allmeans "flag emails from unauthorized servers but don't reject them."-allmeans "reject emails from unauthorized servers." Start with~allto avoid accidentally blocking legitimate email while you're configuring - Check after every new tool is added. Adding a new sequencing tool or marketing platform? Add its SPF include to your record. If you forget, emails from that tool will fail SPF and go to spam
- If you hit the 10-lookup limit: Use an SPF flattening service (like AutoSPF or SPF Record Flattener) to convert includes into IP addresses. Or consolidate sending through fewer services
Common SPF mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| Two SPF records on the domain | Both records are invalid. All SPF checks fail | Merge into one record |
| More than 10 DNS lookups | SPF permanently fails (PermError). All email flagged | Flatten SPF or reduce services |
| Missing an include for a sending service | Emails from that service fail SPF | Audit all sending services. Add missing includes |
Using +all |
Allows anyone to send as your domain. SPF is effectively disabled | Never use +all. Use ~all or -all |
| Forgot to update after switching email providers | Old provider's include still there. New provider's isn't | Audit SPF when changing email infrastructure |
DKIM (DomainKeys Identified Mail)
What DKIM does
DKIM adds a cryptographic signature to every outgoing email. The receiving server checks the signature against a public key published in your DNS. If the signature matches, the email is verified as authentic and unmodified.
How to set it up
DKIM setup varies by provider because each service generates its own key pair.
Step 1: Generate DKIM keys in each sending service
| Service | Where to find DKIM setup |
|---|---|
| Google Workspace | Admin Console → Apps → Gmail → Authenticate Email |
| Microsoft 365 | Defender portal → Email Authentication → DKIM |
| HubSpot | Settings → Domain & URLs → Email Sending → Connect |
| Lemlist | Settings → Email Accounts → DNS Records |
| Outreach | Settings → Email → Domain Authentication |
| Apollo | Settings → Email → Sending domains |
| SendGrid | Settings → Sender Authentication → Domain Authentication |
Step 2: Add DKIM records to DNS
Each service provides a CNAME or TXT record to add. The record looks like:
Type: CNAME (or TXT)
Host: selector._domainkey (e.g., google._domainkey or s1._domainkey)
Value: [provided by the service]
Step 3: Verify in the service
After adding the DNS record, go back to the service and click "Verify." It checks that the DNS record matches the private key.
DKIM rules
- Set up DKIM for every service that sends email from your domain. Not just your primary email provider. Every sequencing tool, every marketing platform, every transactional email service. Each needs its own DKIM record
- Each service uses a different DKIM selector. Google uses
google._domainkey. HubSpot might usehsX._domainkey. You can (and should) have multiple DKIM records, one per service. This is different from SPF (one record only) - DKIM keys should be 2048-bit. Some older services default to 1024-bit. If you have a choice, use 2048-bit for stronger security
- Rotate DKIM keys annually. Most services don't auto-rotate. Set a calendar reminder to regenerate keys once per year
- Test after setup. Send a test email to a Gmail account. Check the email headers (Show Original in Gmail). Look for
dkim=passin the Authentication-Results header
Common DKIM mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| DKIM not set up for sequencing tool | Outbound emails fail DKIM. Go to spam | Add DKIM record for every sending service |
| CNAME record has extra spaces or formatting errors | DKIM verification fails. Silent failure | Copy-paste the exact value. No extra spaces |
| Wrong selector name | DKIM lookup fails. Record not found | Double-check the selector name from the service's setup page |
| DNS propagation not complete | DKIM verification fails temporarily | Wait 24-48 hours after adding the record before verifying. DNS propagation takes time |
DMARC (Domain-based Message Authentication, Reporting & Conformance)
What DMARC does
DMARC tells receiving servers what to do with emails that fail SPF and/or DKIM, and gives you visibility (reports) into who's sending email from your domain.
How to set it up
Step 1: Start with a monitoring-only policy
Type: TXT
Host: _dmarc
Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com; pct=100
This tells receiving servers: "Don't take any action on failed emails, but send me reports about authentication results."
Step 2: Monitor for 2-4 weeks
Review DMARC reports (sent to the rua email address). Look for:
- Legitimate sending services that are failing SPF or DKIM (fix their authentication)
- Unknown senders using your domain (potential spoofing)
- The overall pass/fail ratio
Step 3: Move to quarantine
After confirming all legitimate senders pass SPF and DKIM:
v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; pct=100
This tells receiving servers: "Send emails that fail authentication to the spam folder."
Step 4: Move to reject (optional, recommended for mature setups)
After 30+ days on quarantine with no legitimate failures:
v=DMARC1; p=reject; rua=mailto:dmarc-reports@yourdomain.com; pct=100
This tells receiving servers: "Reject emails that fail authentication entirely."
DMARC progression timeline
| Phase | Policy | Duration | Purpose |
|---|---|---|---|
| 1. Monitor | p=none |
2-4 weeks | Identify all legitimate senders. Fix authentication gaps |
| 2. Quarantine | p=quarantine |
4-8 weeks | Test enforcement. Failed emails go to spam, not rejected |
| 3. Reject | p=reject |
Permanent | Full enforcement. Failed emails are blocked |
DMARC rules
- Always start at
p=none. Going straight top=rejecton a domain that hasn't been audited will block legitimate email from services you forgot to authenticate - Use a DMARC reporting tool. Raw DMARC reports are XML files that are nearly impossible to read. Use a tool like Postmark DMARC, DMARC Analyzer, Valimail, or DMARCian to visualize the reports
- The
ruaaddress must be on the same domain or have explicit authorization. If you want reports sent to a third-party tool, the tool will provide a specific address or require DNS authorization - One DMARC record per domain. Like SPF, only one DMARC TXT record at
_dmarc.yourdomain.com pct=100means the policy applies to 100% of emails. During quarantine testing, you can usepct=25to apply the policy to only 25% of emails. Useful for gradual rollout on high-volume domains
Common DMARC mistakes
| Mistake | Consequence | Fix |
|---|---|---|
Starting at p=reject without monitoring |
Legitimate email gets blocked. Sales can't send | Start at p=none. Monitor. Progress gradually |
No rua address |
No reports. Flying blind on authentication status | Always include rua=mailto:your-address. Use a DMARC reporting tool |
DMARC set to p=none permanently |
No enforcement. Spoofers can still impersonate your domain | Progress to p=quarantine then p=reject after monitoring |
| Forgetting subdomains | Subdomains inherit the parent domain's DMARC policy, but SPF/DKIM must be set up per subdomain | Set up SPF and DKIM for every subdomain that sends email |
| Not monitoring after setup | A new service is added 6 months later without DKIM. Emails fail silently | Review DMARC reports monthly. Check after adding any new sending service |
Setup Checklist (Order Matters)
Before sending any cold email
- [ ] SPF record created with all sending service includes
- [ ] SPF lookup count verified (≤ 10 lookups via MXToolbox)
- [ ] DKIM set up for primary email provider (Google Workspace / Microsoft 365)
- [ ] DKIM set up for every sequencing tool (Lemlist, Outreach, Apollo, etc.)
- [ ] DKIM set up for marketing automation (HubSpot, Marketo, etc.)
- [ ] DKIM set up for transactional email (SendGrid, Postmark, etc.)
- [ ] DKIM verified in each service's admin console
- [ ] DMARC record created at
_dmarc.yourdomain.comwithp=none - [ ] DMARC reporting address (
rua) configured and receiving reports - [ ] Test email sent to Gmail. Headers checked for
spf=pass,dkim=pass,dmarc=pass
After 2-4 weeks of monitoring
- [ ] DMARC reports reviewed. All legitimate senders passing SPF and DKIM
- [ ] Any authentication gaps fixed (missing includes, missing DKIM records)
- [ ] DMARC policy upgraded to
p=quarantine
After 4-8 weeks on quarantine
- [ ] No legitimate email failures in DMARC reports
- [ ] DMARC policy upgraded to
p=reject(optional but recommended)
Monthly maintenance
- [ ] DMARC reports reviewed for new failures or unauthorized senders
- [ ] SPF record audited when adding new sending services
- [ ] DKIM records verified when changing email providers or tools
Verification Tools
| Tool | What it checks | Free? |
|---|---|---|
| MXToolbox (mxtoolbox.com) | SPF, DKIM, DMARC, blacklist, DNS | Free for basic checks |
| Google Admin Toolbox | SPF, DKIM, DMARC lookups | Free |
| Mail-Tester (mail-tester.com) | Full deliverability score including authentication | Free (limited) |
| DMARC Analyzer (dmarcanalyzer.com) | DMARC report visualization | Free tier available |
| Postmark DMARC (dmarc.postmarkapp.com) | Weekly DMARC report digest | Free |
| Valimail | Enterprise DMARC management | Paid |
Verification process
After setup, send a test email to a Gmail address and check the headers:
Open Gmail → Find test email → Three dots → Show Original
Look for:
SPF: PASS
DKIM: PASS
DMARC: PASS
If any show FAIL, debug that specific record before sending cold email.
Subdomain Strategy for Cold Outbound
Most B2B SaaS teams should send cold outbound from a subdomain, not the primary domain.
| Approach | Domain | Example | Use for |
|---|---|---|---|
| Primary domain | company.com | jane@company.com | Team email, customer communication, transactional email |
| Outbound subdomain | outbound.company.com or mail.company.com | jane@mail.company.com | Cold email sequences |
| Marketing subdomain | marketing.company.com or news.company.com | marketing@news.company.com | Marketing email, newsletters |
Why subdomains: Cold outbound carries deliverability risk. Bounces, spam complaints, and low engagement on cold email can damage sender reputation. A subdomain isolates this risk from your primary domain. If mail.company.com gets flagged, company.com is unaffected.
Subdomain rules:
- SPF, DKIM, and DMARC must be set up independently for each subdomain. Subdomains do NOT inherit SPF or DKIM from the parent domain (DMARC policy is inherited but can be overridden)
- The subdomain should be close to the primary domain.
mail.company.comorgo.company.comlooks legitimate.cold-outreach-campaigns.company.comlooks suspicious - Warm up the subdomain before sending cold email. See email-warmup-strategy skill. A new subdomain with no sending history needs 2-4 weeks of warmup
Troubleshooting
| Symptom | Likely cause | How to diagnose | Fix |
|---|---|---|---|
| Emails going to spam | SPF/DKIM/DMARC failing | Check email headers for FAIL. Run MXToolbox | Fix the failing record |
| "550 SPF check failed" bounce | Sending server not in SPF record | Check SPF for missing include | Add the sending service's include |
| DKIM verification fails in service admin | DNS record not propagated or typo | Check the CNAME/TXT record in DNS. Wait 24-48 hours | Correct the record. Wait for propagation |
| DMARC reports show failures from unknown senders | Someone is spoofing your domain | Review the sending IP in the report | Move DMARC to p=quarantine or p=reject to block them |
| SPF PermError | More than 10 DNS lookups | Count lookups with MXToolbox SPF checker | Flatten SPF or consolidate sending services |
| Emails authenticated but still going to spam | Authentication is fine but content, reputation, or engagement is the problem | Authentication passes but spam score is high | Fix content (banned words), sending volume, or domain reputation. Authentication isn't the only factor |
Anti-Pattern Check
- No SPF/DKIM/DMARC and already sending cold email. Stop sending. Set up authentication first. Every email sent without authentication damages domain reputation that will take weeks to recover
- Two SPF records on the domain. Both are invalid. This is the most common SPF mistake. Merge into one record with all includes
- DKIM set up for Google Workspace but not for the sequencing tool. Every outbound email from the sequencing tool fails DKIM and goes to spam. Set up DKIM for every service that sends email
- DMARC at
p=nonefor 6+ months. Monitoring mode is for the first month. After that, progress to quarantine. Permanentp=noneoffers zero protection against spoofing - SPF with 14 lookups. SPF has a hard 10-lookup limit. Exceeding it causes a permanent error that fails every SPF check. Audit and flatten
- Starting DMARC at
p=rejecton Day 1. If any legitimate sending service isn't authenticated, its emails get rejected. Start atp=none, monitor, then progress - Never checking DMARC reports. Reports tell you who's sending email from your domain and whether authentication is passing. Not reading them means you're blind to spoofing and misconfiguration. Review monthly at minimum
- Cold outbound from the primary domain with no subdomain. If cold email damages the primary domain's reputation, customer communication, transactional email, and team email all suffer. Use a subdomain for cold outbound