Email Sending Service Authentication: SPF, DKIM, and DMARC Setup Walkthrough
Email authentication determines whether your email sending service delivers or drains your budget. Misconfigured SPF, DKIM, and DMARC convince mailbox providers your mail is spoofed, and they route it straight to spam.
The failure I see repeatedly: senders add the records, then never check that all three align on the same domain. SPF passes, DKIM passes, DMARC fails. Nobody notices until deliverability tanks. Here's the sequence that prevents that.
SPF: Authorize the sending IP
SPF tells mailbox providers which servers can send from your domain. Without it, your mail looks like anyone could have spoofed it.
Add a TXT record at your root domain (e.g., example.com) with the value your sending service provides. A typical record:
v=spf1 include:spf.your-service.com -all
Replace your-service.com with the provider's SPF include. SendGrid provides include:spf.sendgrid.net. Mailgun uses include:mailgun.org. Postmark uses include:spf.mtasv.net. The -all mechanism is a hard fail: receiving servers reject unlisted IPs outright. If you're still testing, ~all (softfail) is safe, but switch to -all before any real volume.
DKIM: Cryptographic signature
DKIM signs every outgoing message with a private key. The receiving server validates it against a public key you publish in DNS, proving the message is intact and genuinely came from your domain.
The sending service generates a DKIM key pair and tells you the selector (like s1) and the public key string. Create a TXT record under <selector>._domainkey.example.com:
s1._domainkey.example.com → v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQ...
That long p= value is the public key. Copy it exactly. A single misplaced character breaks verification.
DMARC: Policy, alignment, and the safety net
DMARC ties SPF and DKIM together with a policy and tells receivers what to do on failure. Without it, spam filters don't know whether you intended the authentication checks to mean anything.
Start with monitoring. Publish this at _dmarc.example.com:
v=DMARC1; p=none; rua=mailto:dmarc[email protected]; ruf=mailto:dmarc[email protected]; fo=1
p=none means "just report, don't block." That lets you collect data. Once every test email shows dmarc=pass, move to p=quarantine, then finally p=reject, which is the only policy that blocks spoofing.
Alignment is where setups break. DMARC passes only when either SPF or DKIM aligns with the domain in your From header. By default, DMARC uses relaxed alignment: See RFC 7489 — DMARC. the domains just need to share the same organizational root (e.g., bounce.example.com aligns with example.com). That works, as long as your sending service lets you set custom bounce and DKIM domains that match your root domain. If your provider forces a mismatched envelope domain (like using its own return-path), DMARC fails even if spf=pass and dkim=pass show in headers. Read your provider's documentation on custom return-path and DKIM domain configuration. If they don't support it, find one that does.
Field note: I've audited setups where DKIM signs with d=your-service.com even though the From header says yourdomain.com. DMARC fails because the signature's domain doesn't match, even if spf=pass and dkim=pass light up in the headers. Always check the dkim=pass (domain:...) line in the authentication results.
Verification before production
Quick reality check: You don't need a paid tool for this step. MXToolbox's SPF checker, DKIM validator, and DMARC lookup, plus dmarcian's domain inspector, all give you a pass/fail verdict in seconds.
The real test is sending a live message to a Gmail address, opening the original message headers, and looking at the Authentication-Results block. You want:
spf=pass smtp.mailfrom=example.com; dkim=pass [email protected]; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com
If dmarc=pass isn't there, tighten alignment or fix the misconfiguration before a single production email hits a real inbox.
Send that test email to yourself right after adding DNS records. It catches misalignment that DNS checkers miss, and a few extra minutes here saves weeks of reputation repair later.
I configured DMARC monitoring on a transactional domain before moving to reject policy, and the reports surfaced alignment failures caused by a DKIM selector mismatch that a quick DNS check would have missed.