If your app sends email — transactional messages, notifications, marketing — you need to understand SPF, DKIM, and DMARC. Not because they're interesting (they're DNS records), but because getting them wrong means your emails go to spam. Or worse, get rejected entirely.
This guide explains all three protocols in practical terms, shows you how to check them programmatically, and covers the mistakes that trip up most developers.
The Core Problem
SMTP, the protocol that sends email, was designed in 1982. It has zero built-in sender verification. Anyone can claim to send email from ceo@yourcompany.com — the protocol doesn't care. SPF, DKIM, and DMARC are patches that add identity verification on top of SMTP.
Here's what each one does, in plain English:
- SPF — "Here's a list of servers allowed to send email from our domain."
- DKIM — "Here's a cryptographic signature proving this email is legit and unmodified."
- DMARC — "Here's what to do if SPF and DKIM checks fail."
SPF (Sender Policy Framework)
SPF is a DNS TXT record that lists which IP addresses can send email for your domain. When a receiving server gets an email claiming to be from @yourdomain.com, it checks your SPF record to see if the sending server's IP is authorized.
Example SPF record
v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.5 -all
This says: "Google Workspace, SendGrid, and IP 203.0.113.5 can send email for us. Reject everything else (-all)."
SPF pitfalls developers hit
- The 10-lookup limit: Each
include:triggers DNS lookups, and SPF allows a maximum of 10. If you use Google Workspace + SendGrid + Mailchimp + HubSpot, you're probably over the limit. SPF silently fails. - Using
~allin production: Softfail (~all) is for testing. Use-all(hardfail) in production. - Forgetting subdomains:
mail.yourdomain.comneeds its own SPF record.
Check SPF from the command line
dig +short TXT yourdomain.com | grep spf
# "v=spf1 include:_spf.google.com -all"
DKIM (DomainKeys Identified Mail)
DKIM signs outgoing emails with a private key. The matching public key lives in a DNS TXT record. When a receiving server gets the email, it fetches the public key and verifies the signature — confirming the email wasn't tampered with and actually came from your infrastructure.
How DKIM signatures work
Your email gets a header like this:
DKIM-Signature: v=1; a=rsa-sha256; d=yourdomain.com; s=mail;
h=from:to:subject:date; bh=abc123...; b=xyz789...
The receiving server looks up mail._domainkey.yourdomain.com to get the public key and verify the signature.
DKIM mistakes to avoid
- Not using custom DKIM: If your ESP (SendGrid, Postmark, etc.) signs with their domain instead of yours, DMARC alignment fails. Always set up custom DKIM signing.
- 1024-bit keys: They're increasingly breakable. Use 2048-bit keys.
- Never rotating keys: Rotate annually as a security best practice.
Check DKIM from the command line
# You need to know the selector (check your ESP's docs)
dig +short TXT mail._domainkey.yourdomain.com
DMARC (Domain-based Message Authentication, Reporting & Conformance)
DMARC is the policy layer. It tells receiving servers: "If an email claims to be from our domain and both SPF and DKIM fail to align, do X." The policy options are:
p=none— just monitor (send reports, don't act)p=quarantine— send to spamp=reject— drop the email entirely
Example DMARC record
v=DMARC1; p=reject; rua=mailto:dmarc-reports@yourdomain.com; adkim=s; aspf=r
The alignment trap
This is where most developers get confused. DMARC doesn't just check if SPF/DKIM pass — it checks if they align with the From: header domain.
Example: You send email with From: noreply@yourdomain.com, but your ESP uses bounce@sendgrid.net as the envelope sender. SPF passes for sendgrid.net, but DMARC fails because sendgrid.net ≠ yourdomain.com.
Fix: Configure your ESP to use your domain for both the envelope sender and DKIM signing.
Check DMARC from the command line
dig +short TXT _dmarc.yourdomain.com
# "v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com"
Checking All Three Programmatically
If you're building an onboarding flow that needs to verify a customer's email authentication, or you want to monitor your own domain's setup, the MailCheck API lets you check everything in one call:
curl
curl -X POST https://api.mailcheck.dev/v1/verify \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key" \
-d '{"email": "user@yourdomain.com"}'
JavaScript (fetch)
async function checkEmailAuth(email) {
const res = await fetch('https://api.mailcheck.dev/v1/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your_api_key',
},
body: JSON.stringify({ email }),
});
const data = await res.json();
console.log('Valid:', data.valid);
console.log('MX found:', data.mx_found);
console.log('Disposable:', data.disposable);
return data;
}
// Check a domain's email setup
checkEmailAuth('test@yourdomain.com');
The response tells you whether the domain has valid MX records, passes authentication checks, and flags any configuration issues — all without you needing to implement DNS lookups yourself.
The Recommended Setup Checklist
- SPF: List all legitimate sending sources. Stay under 10 lookups. End with
-all. - DKIM: Configure custom signing on every ESP. Use 2048-bit keys. Rotate yearly.
- DMARC: Start with
p=noneandrua=to collect reports. Analyze for 2-4 weeks. Fix alignment issues. Upgrade top=quarantine, thenp=reject. - Monitor: DMARC aggregate reports show you who's sending email as your domain — both legitimate and malicious. Review them regularly.
What Happens When You Get It Wrong
- No SPF/DKIM/DMARC: Your domain is wide open for spoofing. Phishers can send emails as
@yourdomain.com. - SPF over 10 lookups: SPF silently fails. You think you're protected, but you're not.
- DKIM misaligned: DMARC fails even though DKIM technically passes. Your legitimate emails go to spam.
- DMARC on
p=noneforever: You're monitoring but not protecting. Phishers can still spoof your domain.
Email authentication isn't optional anymore. Gmail and Yahoo now require SPF, DKIM, and DMARC for bulk senders. Get it right, and your emails reach the inbox. Get it wrong, and they don't.
Use MailCheck to verify SPF, DKIM, and DMARC configuration for any domain. 100 free checks per day — no credit card required. Get your free API key →