SPF, DKIM, and DMARC Explained: How Email Authentication Works

Email was designed in 1971 with no built-in way to verify the sender. The "From" header is just text the sending server fills in, and for decades anyone could put anything there. That made phishing trivial: an attacker could send a message claiming to be from your bank, your boss, or you, and the receiving server had no protocol-level way to know whether it was real.

SPF, DKIM, and DMARC are the three protocols built on top of email over the past two decades to fix this. Each one closes a different gap, and the three are designed to work as a layered system. Understanding what each one actually does (and why all three exist) makes the difference between an authentication setup that protects your domain and one that quietly fails in ways you only discover when your messages start landing in spam.

Why Three Protocols Instead of One

Each protocol answers a different question, and any single one leaves a gap that the others fill.

SPF verifies which servers are allowed to send email for your domain. It catches the case where an attacker tries to send mail from an unauthorized server. SPF can't see the message contents and doesn't care whether anything was modified after it was sent.

DKIM verifies that the message wasn't tampered with in transit. It catches the case where someone intercepts a message and modifies it before delivery. DKIM doesn't care which server sent the message; it only verifies that the contents match what was originally signed.

DMARC doesn't authenticate anything itself. It tells receiving servers what to do when SPF or DKIM checks produce mixed or unexpected results, and it provides a reporting channel so domain owners can see what's happening. Without DMARC, mailbox providers each apply their own logic when authentication is partial or fails. With DMARC, you control the policy.

📊
Key Stat

Two years after Gmail and Yahoo introduced bulk sender requirements, roughly 30 percent of senders are still partially non-compliant on at least one protocol. Microsoft began rejecting non-compliant mail from bulk senders to Outlook.com in May 2025. Apple iCloud Mail is widely expected to follow.

SPF: Sender Policy Framework

SPF (defined in RFC 7208) is the oldest of the three. The idea is straightforward: publish a list of IP addresses authorized to send mail for your domain, and let receiving servers check each incoming message against that list.

When a receiving server gets a message, it looks at the envelope sender (the address used in the SMTP MAIL FROM command, also called the Return-Path) and queries DNS for the SPF record on that domain. If the IP that delivered the message is on the list, SPF passes. If not, SPF fails.

Anatomy of an SPF record

An SPF record is a TXT record published at the apex of your domain. Here's a typical one:

DNS TXT record
# Published as a TXT record on example.com
"v=spf1 ip4:198.51.100.10 include:_spf.google.com include:mailgun.org -all"

# Breaking it down piece by piece:
#
# v=spf1                  Required version tag. Always spf1.
#
# ip4:198.51.100.10       Authorize this specific IPv4 address.
#                         Use ip6: for IPv6.
#
# include:_spf.google.com Authorize whatever IPs Google publishes
#                         in their own SPF record. Used when you
#                         send mail through Google Workspace.
#
# include:mailgun.org     Same idea, but for Mailgun.
#                         Add an include: for every service that
#                         sends mail on your behalf.
#
# -all                    The "all" mechanism is the catchall at
#                         the end. The qualifier in front controls
#                         what receivers do with mail from IPs not
#                         in the list:
#
#                           -all  Hard fail. Reject the message.
#                           ~all  Soft fail. Accept but mark suspicious.
#                           ?all  Neutral. No opinion.
#                           +all  Allow everything. Never use this.

The hard fail (-all) is the strict, modern recommendation. The soft fail (~all) is what most senders use during initial rollout to avoid breaking edge cases while they build confidence in the configuration.

Where SPF breaks

⚠️
The 10-Lookup Limit

SPF has a hard limit of 10 DNS lookups per evaluation, including any nested lookups inside include: mechanisms. Most senders unknowingly exceed this limit by stacking multiple email services (Google + Mailgun + SendGrid + a marketing platform), and the entire SPF record fails silently when over the limit. Use an SPF flattening tool or consolidate sending services to stay under 10.

SPF also breaks on email forwarding. When a recipient forwards your message to another address, the forwarding server delivers it from its own IP, which isn't on your SPF record. SPF fails on the forwarded message even though the original was legitimate. This is one of the main reasons DKIM and DMARC exist; SPF alone can't handle the forwarding case.

DKIM: DomainKeys Identified Mail

DKIM (RFC 6376) takes a different approach. Instead of verifying which server sent the message, DKIM cryptographically signs each message before it leaves the sending server. The signature proves that the message contents (and specific headers) were created by someone holding the private key for your domain, and that nothing was modified after signing.

Here's the basic flow. Your mail server holds a private key. You publish the matching public key in DNS as a TXT record at a specific subdomain (called the selector). When you send a message, the server uses the private key to compute a signature over selected headers and the message body, then attaches the signature in a header called DKIM-Signature. When the receiving server gets the message, it reads the signature header, looks up the public key in your DNS, and verifies the signature against the message contents.

If the verification succeeds, DKIM passes. If the signature is invalid, the public key isn't found, or the message has been modified in transit, DKIM fails.

Anatomy of a DKIM record

DKIM signature header + DNS record
# Header attached to outbound messages by the sending server:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=mail2026;
   c=relaxed/relaxed; q=dns/txt; t=1715000000;
   h=from:to:subject:date;
   bh=K8wEKZdyV8tZ...; b=Mh+DjP9GqW...

# Public key DNS record published at:
#   mail2026._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB..."

# Header field meanings:
#
# v=1            DKIM version. Always 1.
# a=rsa-sha256   Signing algorithm.
# d=example.com  Signing domain. Must align with From: for DMARC.
# s=mail2026     Selector. Used to find the public key in DNS.
# c=relaxed/...  Canonicalization (how whitespace is normalized).
# h=...          Which headers were included in the signature.
# bh=...         Hash of the message body.
# b=...          The actual signature.

The selector exists so you can rotate keys without service interruption. You publish a new key under a new selector (e.g., mail2027._domainkey.example.com), switch your sending server to sign with the new key, and remove the old DNS record after the cutover.

Where DKIM breaks

The most common DKIM failure is a key that's too short. Older setups used 1024-bit keys, which are now considered weak. Modern best practice is 2048 bits, which is too long for some DNS providers' single-record TXT field and has to be split across multiple quoted strings. The sending server doesn't know about the DNS limit and will keep signing with the full 2048-bit key; if the public key in DNS is truncated or malformed, DKIM fails on every message.

DKIM also fails when intermediate servers modify the message after signing. Mailing lists are a frequent culprit because many of them prepend tags to the subject line ("[my-list]") or append unsubscribe footers, both of which break the body hash and invalidate the signature. The Authenticated Received Chain (ARC) protocol exists specifically to handle this case for forwarders that opt in.

DMARC: Domain-based Message Authentication, Reporting, and Conformance

DMARC (RFC 7489) sits on top of SPF and DKIM. It does three things that neither of the underlying protocols handles:

Defines what counts as authenticated. DMARC requires that at least one of SPF or DKIM passes and aligns with the visible From header (the address users actually see). This alignment requirement is what ties authentication to the identity recipients see, which neither SPF nor DKIM does on its own.

Sets the policy for failures. When a message doesn't pass DMARC, the receiving server consults your DMARC policy to decide what to do: nothing (just monitor), quarantine (route to spam), or reject (refuse delivery entirely).

Provides reporting. Receiving servers send aggregate reports back to the address you specify, telling you which IPs are sending mail claiming to be from your domain, which messages passed authentication, and which failed. This is invaluable visibility that neither SPF nor DKIM provides.

Anatomy of a DMARC record

DNS TXT record at _dmarc.example.com
# Published as TXT at _dmarc.example.com
"v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com; ruf=mailto:forensic@example.com; pct=100; adkim=s; aspf=s; fo=1"

# Tag by tag:
#
# v=DMARC1   Version. Always DMARC1.
#
# p=reject   The policy. One of:
#              none        Monitor only. Take no action on failures.
#              quarantine  Route failing messages to spam.
#              reject      Refuse failing messages entirely.
#
# rua=...    Aggregate report destination.
#            Daily summary of pass/fail rates by IP.
#
# ruf=...    Forensic report destination.
#            Per-message details of failures (verbose, can be large).
#
# pct=100    Percentage of failing messages the policy applies to.
#            Used to ramp gradually: start at 10, climb to 100.
#
# adkim=s    DKIM alignment mode: s=strict, r=relaxed.
#            Strict requires exact domain match.
#            Relaxed allows organizational domain match.
#
# aspf=s     SPF alignment mode. Same options as adkim.
#
# fo=1       Generate forensic report when any check fails.
#            Default is 0 (only when both fail).

The three policy levels

p=none
Monitor

Receivers take no action on failures. Reports still flow. Use this during initial DMARC rollout to see what's happening before you start blocking anything.

p=quarantine
Spam folder

Receivers route failing messages to the spam folder. The intermediate enforcement level. Senders typically run here for several months while resolving edge cases.

p=reject
Block

Receivers refuse failing messages entirely. The strict enforcement level. Required for some advanced features like BIMI brand indicators.

The standard rollout pattern is none for 1 to 3 months, quarantine for 1 to 3 months, then reject. Each step gives you time to identify and fix any legitimate sending sources that are failing authentication before you start losing real mail to enforcement.

DMARC reports (the underrated feature)

💡
Pro Tip

Most teams set up DMARC and never look at the reports. The reports are the most valuable part. They reveal every IP and service sending mail claiming to be from your domain, including ones you forgot about (an old marketing tool, a SaaS vendor that sends notifications, a legacy server you thought was decommissioned). Use a DMARC report parser like Postmark, dmarcian, or EasyDMARC to turn the raw XML into something readable.

How They Work Together

Think of the three protocols as a layered defense. A message has to clear all three layers (or at least the parts that DMARC requires) to be considered authenticated.

The receiving server runs SPF first by checking the sending IP against the envelope-sender domain's SPF record. Then it runs DKIM by reading the signature header, fetching the public key from DNS, and verifying the signature against the message contents. Finally, it runs DMARC by checking that at least one of SPF or DKIM passed and that the passing protocol's domain aligns with the visible From header.

If DMARC passes, the message is authenticated and the receiver delivers it normally. If DMARC fails, the receiver applies the policy you've published: monitor, quarantine, or reject.

ProtocolWhat it verifiesWhat it doesn't do
SPFSending server is on your authorized IP listDoesn't check message contents or visible From header
DKIMMessage contents and selected headers weren't modified after signingDoesn't check which IP sent the message or whether the signing domain matches the From header
DMARCSPF or DKIM passed AND the passing domain aligns with visible From headerDoesn't authenticate anything itself; relies entirely on SPF and DKIM results

The Alignment Requirement (Where Most Setups Quietly Fail)

This is the part that catches the most senders off guard. SPF and DKIM can both pass on a message and DMARC can still fail, because of alignment.

SPF authenticates the envelope sender (the MAIL FROM domain), which is often different from the visible From header. DKIM authenticates whichever domain signed the message, which can also differ from From. DMARC requires that at least one of those authenticated domains matches the visible From header (either exactly, in strict mode, or by sharing the same organizational domain, in relaxed mode).

The most common alignment failure: you send mail through a third-party service that uses its own envelope sender (so SPF passes for the third party's domain but not yours), and either doesn't sign with DKIM at all or signs with its own domain rather than yours. SPF and DKIM might both technically pass, but neither authenticated domain aligns with your visible From, so DMARC fails.

The fix is to configure the third-party service to sign DKIM with your domain (most modern services support this) or to set up your own subdomain as the envelope sender for that service. The setup details vary by service, but every credible email platform has documentation for DMARC alignment.

Reading Authentication Results in Email Headers

Every authenticated message includes an Authentication-Results header showing what the receiving server determined for each protocol. Here's a real example:

Authentication-Results header
Authentication-Results: mx.google.com;
   spf=pass (google.com: domain of bounces@example.com
       designates 198.51.100.10 as permitted sender) smtp.mailfrom=bounces@example.com;
   dkim=pass header.i=@example.com header.s=mail2026 header.b=Mh+DjP9G;
   dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com

# Reading this:
# spf=pass    The envelope sender domain authorized this IP.
# dkim=pass   The signature verified against the message contents.
#             header.i shows the signing identity.
#             header.s shows the selector used to find the public key.
# dmarc=pass  At least one of SPF/DKIM passed AND aligned with the
#             visible From header (header.from=example.com).
#             p=REJECT shows the policy you have published.

You can view this header on any received message: in Gmail, click the three-dot menu and choose "Show original." In Outlook, open the message properties. The header is your fastest diagnostic tool when something looks wrong.

Common Misunderstandings

"DMARC authenticates messages." No. DMARC has no authentication mechanism of its own. It's a policy and reporting layer that operates on SPF and DKIM results.

"If SPF passes, I'm fine." SPF alone doesn't protect against spoofing of the visible From header, doesn't survive forwarding, and doesn't cover message tampering. SPF passing is necessary but not sufficient.

"DMARC at p=none is good enough." Monitoring is a starting point, not a destination. p=none tells receivers to take no action on failures, which means anyone can still spoof your domain and reach the inbox. Move to quarantine or reject to actually block spoofing.

"More authentication is always better." Aggressive policies (p=reject) can block legitimate mail if you haven't identified all your sending sources first. Run at p=none long enough to see what's actually happening before enforcing.

"Only big companies need this." Bulk sender requirements specifically target high-volume sending, but the same enforcement patterns apply at smaller scales. Mid-volume senders see degraded deliverability without proper authentication just as bulk senders do.

For step-by-step setup of all three records (where to publish them, how to verify them, how to fix common errors), see the email deliverability best practices guide for the broader context this fits into.

Frequently Asked Questions

Do I need all three of SPF, DKIM, and DMARC?

For any sender doing meaningful volume to Gmail, Yahoo, or Microsoft inboxes, yes. Bulk senders (5,000+ daily messages to a single provider) are explicitly required to have all three. Smaller senders see the same enforcement patterns at smaller scales, so the requirement is functional even if not formal.

Can I use SPF without DKIM and DMARC?

Technically, yes, but you'll see degraded deliverability and no protection against spoofing of your From header. SPF alone hasn't been adequate for over a decade. The current standard expectation from mailbox providers is all three.

What happens if my SPF record exceeds the 10-lookup limit?

The entire SPF evaluation returns "PermError," which most mailbox providers treat as a fail. The record stops working silently. Use an SPF flattening service or consolidate sending services to stay under the limit.

Should I start DMARC at p=none, p=quarantine, or p=reject?

Start at p=none for at least 30 days to gather reports and identify all your sending sources. Move to p=quarantine after fixing any unauthorized or misconfigured senders. Move to p=reject once you're confident the quarantine policy isn't catching legitimate mail. Most senders complete this rollout in 3 to 6 months.

How do I check if SPF, DKIM, and DMARC are set up correctly on my domain?

The fastest way is to send a test message to a Gmail or Yahoo account and view the original headers. The Authentication-Results header shows pass/fail for each protocol. Several free tools also exist that query your DNS records and validate them against the relevant RFCs (mxtoolbox, dmarcian, EasyDMARC).

What to Do With This

SPF, DKIM, and DMARC stop being abstract once you understand what each one verifies and why all three exist. SPF authorizes servers, DKIM cryptographically signs messages, and DMARC ties both to your visible From header with a policy and reporting layer. Together they form the authentication foundation that every modern deliverability practice depends on.

The implementation work is straightforward, but the operational discipline matters more: publish all three records, monitor your DMARC reports, ramp policy gradually, and watch for the alignment failures that don't show up in basic checks. Get those right and authentication stops being a deliverability problem.

Try It Yourself

Send a test message to a Gmail address you control, view the original headers, and read the Authentication-Results line to see how your domain's setup actually performs in the wild. While you're cleaning up infrastructure, the free email checker verifies addresses against the same authentication signals receivers care about, and bulk email verification handles full lists at pay-as-you-go pricing.

99.7% Accuracy Guarantee

Stop Bouncing. Start Converting.

Millions of emails verified daily. Industry-leading SMTP validation engine.