Back to blog
Email AuthenticationDNSDeveloper Guide

DKIM, SPF, and DMARC Explained Simply

A developer-friendly explanation of email authentication. What these acronyms mean, why they matter, and how to set them up correctly.

SendPigeon TeamNovember 28, 20257 min read

Your password reset emails are landing in spam. Users can't log in. Support tickets pile up. You check your code—it's fine. The email was sent. So where did it go?

The culprit: three missing DNS records.

TL;DR
ProtocolWhat it doesAnalogy
SPFLists which servers can send email for your domainGuest list
DKIMAdds a digital signature proving the email wasn't tampered withWax seal
DMARCTells receivers what to do when SPF/DKIM failRule book

All three work together. Missing any one weakens the whole system.

The Problem These Solve

Email was invented in 1971. Security wasn't a priority. Anyone can send an email claiming to be from ceo@yourcompany.com. That's how phishing works.

SPF, DKIM, and DMARC are band-aids on this fundamental design flaw. They let receiving servers verify that you're actually authorized to send email from your domain.

Without authentication, your emails look like this to Gmail:

Not Authenticated
Authentication-Results: mx.google.com;
spf=none (no SPF record found)
dkim=none (no signature)
dmarc=fail

With proper setup:

Authenticated
Authentication-Results: mx.google.com;
spf=pass (domain of hello@yourdomain.com designates 123.45.67.89 as permitted sender)
dkim=pass header.d=yourdomain.com header.s=sendpigeon
dmarc=pass (p=QUARANTINE)

The difference between inbox and spam.


SPF: Who Can Send

What it does: Lists which servers are allowed to send email for your domain.

Analogy: It's like a guest list. "These IP addresses/services are authorized to speak on my behalf."

How it works

  1. You publish a TXT record in DNS
  2. Receiving server gets an email "from" your domain
  3. Server checks: "Is the sending IP on the SPF list?"
  4. If yes, pass. If no, fail.

Example record

v=spf1 include:sendpigeon.com include:_spf.google.com ~all
PartMeaning
v=spf1Version 1 of SPF
include:sendpigeon.comTrust servers listed in SendPigeon's SPF
include:_spf.google.comAlso trust Google (if you use Gmail)
~allSoft fail everything else (treat with suspicion but don't reject)

Common mistakes

  • Too many lookups: SPF allows max 10 DNS lookups. Each include counts.
  • Using +all: This authorizes everyone. Never do this.
  • Forgetting a service: If you use Mailchimp AND SendPigeon, include both.

DKIM: Message Integrity

What it does: Adds a digital signature to prove the email wasn't modified in transit.

Analogy: It's like a wax seal on a letter. If the seal is broken, you know someone tampered with it.

How it works

  1. You generate a public/private key pair
  2. Public key goes in DNS as a TXT record
  3. When you send an email, your server signs it with the private key
  4. Receiving server uses the public key to verify the signature

Example DNS record

sendpigeon._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIGfMA0GCS..."

The record name format is selector._domainkey.yourdomain.com. The selector (like sendpigeon) identifies which key to use—you can have multiple.

What gets signed

DKIM signs specific headers and the body:

  • From address
  • Subject
  • Date
  • Body content hash

If any of these change after signing, verification fails.

What a DKIM header looks like

When you inspect an email's raw headers, you'll see something like:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
  d=yourdomain.com; s=sendpigeon;
  h=from:to:subject:date:message-id;
  bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
  b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqOB...

Common mistakes

  • Key too short: Use at least 1024-bit keys. 2048-bit is better.
  • Forgetting to rotate: Keys should be rotated periodically.
  • Wrong selector: Make sure you're using the selector your email provider gave you.

DMARC: The Policy Layer

What it does: Tells receiving servers what to do when SPF/DKIM fail, and where to send reports.

Analogy: It's the rule book. "If authentication fails, here's what you should do about it."

How it works

  1. Receiving server checks SPF and DKIM
  2. Receiving server looks up your DMARC policy
  3. If SPF or DKIM fails, server follows your policy
  4. Server sends you a report about what happened

Example record

_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com"
PartMeaning
v=DMARC1Version 1 of DMARC
p=quarantinePut failing emails in spam
rua=mailto:...Send aggregate reports to this address

Policy progression

Start permissive and tighten gradually:

PolicyWhat happensWhen to use
p=noneMonitor only. No action taken.Start here. See what's happening.
p=quarantineFailures go to spam.After 2-4 weeks of monitoring.
p=rejectFailures blocked entirely.When you're confident everything's set up.

Don't jump to p=reject immediately. You'll block legitimate email you forgot about—like that newsletter service your marketing team set up last year.

DMARC alignment

Here's the tricky part. DMARC requires "alignment"—the domain in the From header must match:

  • The domain that passed SPF, OR
  • The domain that signed with DKIM

If your From address is hello@myapp.com, but you send through a service that uses bounce.emailservice.com for SPF... that's a mismatch. You need DKIM alignment instead.


How They Work Together

Email arrives from "you@yourdomain.com"
    │
    ├─► SPF Check: Is sending IP authorized?
    │       └─► Pass/Fail
    │
    ├─► DKIM Check: Is signature valid?
    │       └─► Pass/Fail
    │
    └─► DMARC Check: Did either SPF or DKIM pass WITH alignment?
            │
            ├─► Yes → Deliver normally
            └─► No → Apply DMARC policy (none/quarantine/reject)

Quick Setup

1

Set up SPF

Add a TXT record to your domain's DNS:

v=spf1 include:YOUR_EMAIL_PROVIDER ~all

Replace YOUR_EMAIL_PROVIDER with your actual provider's include (e.g., sendpigeon.com).

2

Set up DKIM

Get the DKIM record from your email provider's dashboard. It'll look something like:

sendpigeon._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIGf..."

Add it to your DNS, then enable DKIM signing in your provider's settings.

3

Set up DMARC

Add a TXT record at _dmarc.yourdomain.com:

v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com

Start with p=none to monitor without affecting delivery.

4

Verify everything

Send a test email to yourself. View the original/raw message and look for:

  • spf=pass
  • dkim=pass
  • dmarc=pass

In Gmail: Open email → Three dots → "Show original"

5

Tighten DMARC policy

After a few weeks of monitoring reports, upgrade from p=nonep=quarantinep=reject.


Tools for Testing


Bottom Line

  • SPF = Who can send
  • DKIM = Message wasn't tampered
  • DMARC = What to do when checks fail

Set them up, monitor the reports, and gradually enforce stricter policies. Your emails will thank you.


Next Steps