How to Fix SPF, DKIM, and DMARC in 2025
Table of Contents
The Problem: Why Your Emails Disappear
If you're reading this, you've probably discovered that 20% of legitimate business emails never reach the inbox. Not because of spam filters โ because of DNS misconfiguration. SPF records with too many lookups, DKIM keys that are too short, DMARC policies set to p=none โ these silently destroy your deliverability every single day.
The worst part? Most organizations don't know they have a problem until they check. Let's fix that.
yourdomain.com with your actual domain.Fixing SPF (Sender Policy Framework)
Common SPF Problems
Problem 1: Multiple SPF records. This is the #1 error we see. Having more than one SPF record is invalid per RFC 7208 and causes receivers to reject your email entirely.
# โ WRONG โ two separate TXT records
v=spf1 include:_spf.google.com ~all
v=spf1 include:sendgrid.net ~all
# โ
CORRECT โ single merged record
v=spf1 include:_spf.google.com include:sendgrid.net ~all
Problem 2: DNS lookup limit exceeded. SPF allows a maximum of 10 DNS lookups. Each include, a, mx, or redirect mechanism counts as a lookup. If you use Google Workspace + SendGrid + Mailchimp + Salesforce, you're already at 8-9 lookups before anything else.
PermError โ receivers treat your SPF as invalid, which means your email fails SPF checks entirely.The Fix
- Merge multiple SPF records into one
- Count your lookups โ use mailcheck to see your exact count
- Use SPF flattening โ services like Valimail or self-hosted tools replace
includedirectives with their resolved IP addresses - Use
~all(softfail) if you're not sure all senders are listed;-all(hardfail) only when 100% certain
Fixing DKIM (DomainKeys Identified Mail)
Common DKIM Problems
Problem 1: Key too short. Many providers still use 1024-bit DKIM keys. This is considered cryptographically weak and some receivers (notably Microsoft) may silently penalize you.
# โ 1024-bit key (weak)
k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ...
# โ
2048-bit or larger key
k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...
Problem 2: Missing selector records. DKIM requires a specific selector subdomain (selector._domainkey.yourdomain.com). If your email provider changed the selector and didn't update DNS, DKIM breaks silently.
The Fix
- Rotate to 2048+ bit keys โ check all your selectors with mailcheck which scans 19+ common selectors
- Use multiple selectors โ
s1,s2,google,mailโ to cover provider-specific configurations - Set key rotation schedule โ rotate DKIM keys annually; don't wait for a breach
- Monitor continuously โ DKIM breaks when providers rotate keys without updating your DNS
Fixing DMARC (Domain-based Message Authentication)
Common DMARC Problems
Problem 1: p=none is the new "no DMARC." Over 60% of domains with DMARC use p=none. This tells receivers "do nothing if authentication fails" โ which means spoofing is still possible. Gmail and Microsoft increasingly treat p=none as no DMARC at all.
# โ Weak โ doesn't prevent spoofing
v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com
# โ
Strong โ rejects unauthenticated email
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@yourdomain.com; pct=100
Problem 2: No reporting address. Without rua, you'll never know who's failing authentication. Reports are free intelligence about email abuse targeting your domain.
The Fix (Gradual Rollout)
- Start with
p=none+ruaโ collect aggregate reports for 2 weeks - Analyze reports โ identify all legitimate sending sources
- Move to
p=quarantineโ failed auth goes to spam - After 2-4 weeks of clean reports โ move to
p=reject - Set
sp=rejectโ protect subdomains too
Bonus: MTA-STS and TLS-RPT
If you're serious about email security, MTA-STS (RFC 8461) prevents SMTP downgrade attacks by publishing a policy via HTTPS that says "only accept TLS connections for this domain."
Without MTA-STS, an attacker on the network path can strip TLS during SMTP delivery, reading your emails in transit. This is not theoretical โ it's been documented against EU government mail servers.
# DNS record for MTA-STS
_mta-sts.yourdomain.com. TXT "v=STSv1; id=20250401000000"
# HTTPS policy served at:
# https://mta-sts.yourdomain.com/.well-known/mta-sts.txt
version: STSv1
mode: enforce
mx: mail.yourdomain.com
max_age: 604800
Automate With mailcheck
Checking all of this manually is time-consuming and error-prone. mailcheck automates it:
# Install
pip install mailcheck --index-url https://korpo.pro/git/api/packages/mailcheck/pypi/simple/
# Check any domain
mailcheck yourdomain.com
# JSON output for scripts
mailcheck yourdomain.com --json
# REST API
curl https://korpo.pro/api/v1/check/yourdomain.com
mailcheck checks SPF, DKIM (19+ selectors), DMARC, and returns a 0-100 deliverability score with plain-English recommendations for every issue found.