SPF DKIM DMARC explained is one of the most searched topics in email deliverability, and most guides answer it wrong. They present three setup checklists instead of one interacting system. The result is practitioners who deploy all three protocols, watch a message fail DMARC, and have no idea why SPF passing was never enough. This article walks through what each protocol actually checks at the MTA level, where they hand off to each other, and how the header evidence tells the story when something breaks.

Why Three Protocols Exist, and Why None of Them Works Alone

Email's original design had no authentication layer. SMTP accepts whatever the sending server declares in its MAIL FROM and EHLO commands, there is no built-in mechanism to verify those claims. That gap produced three separate protocols, each closing a different attack surface.

What Each Protocol Actually Authenticates

SPF (Sender Policy Framework) answers one question: is this IP address authorized to send mail for this domain? It checks the envelope sender, the MAIL FROM value in the SMTP transaction, against a DNS record listing permitted sending IPs. SPF says nothing about the message content or the From header the recipient reads.

DKIM (DomainKeys Identified Mail) answers a different question: has this message been altered in transit, and does a specific domain vouch for it? A signing server adds a DKIM-Signature header containing a cryptographic hash of the message. The receiving MTA fetches the corresponding public key from DNS and verifies the signature. DKIM says nothing about which IP sent the message.

DMARC (Domain-based Message Authentication, Reporting & Conformance) ties both together and adds one critical requirement: the authenticated domain must align with the From header domain the recipient actually sees. DMARC also defines what the receiving MTA should do with a failing message and where to send reports.

None of the three works alone because each one only closes part of the surface. SPF without DMARC can be satisfied by a completely unrelated domain's infrastructure. DKIM without DMARC proves integrity but not identity, a message signed by newsletter-platform.com tells you nothing about whether yourbank.com authorized it. DMARC without SPF or DKIM has nothing to align against.

SPF Record Validation: What the Receiving MTA Actually Checks

When a message arrives, the receiving MTA extracts the domain from the RFC 5321 MAIL FROM command, the envelope sender, not the visible From header. It constructs a DNS TXT query for that domain and evaluates the returned SPF record.

The MTA reads SPF mechanisms left to right: ip4:, ip6:, a, mx, include:, and others. Each mechanism either matches the connecting IP or it doesn't. The first match determines the result. If no mechanism matches, the default result is neutral unless an explicit all mechanism ends the record.

SPF Softfail vs Hardfail and Why the Difference Matters

The all mechanism carries a qualifier that changes the result's meaning:

  • -all (hardfail): any IP not matched by a prior mechanism fails SPF. The record says "no other server is authorized."
  • ~all (softfail): unmatched IPs produce a softfail result. The record says "probably not authorized, but don't reject outright."

The operational difference is significant. A hardfail gives receiving MTAs clear grounds to reject. A softfail is advisory, most receivers accept the message and tag it, or route it to spam, but they do not reject at the SMTP level. Many organizations publish ~all during a migration to avoid dropping legitimate mail while they audit their sending infrastructure. Leaving it there permanently undermines the signal.

One fact that catches people out: SPF evaluates the envelope MAIL FROM, not the header From. Those two domains are frequently different by design, and that gap is precisely the attack surface DMARC was built to close. More on that in the alignment section below.

DKIM Signature Verification: From Selector Lookup to Header Hash

DKIM verification at the receiving MTA is a four-step chain. Get any step wrong and the result is either a hard failure or no result at all.

Reading the DKIM-Signature Header Field

The DKIM-Signature header carries all the information needed for verification. Key tags:

  • d=, the signing domain (e.g. d=example.com)
  • s=, the selector (e.g. s=mail2026)
  • bh=, the base64-encoded body hash
  • b=, the base64-encoded signature of the selected headers
  • h=, the list of headers that were signed
  • c=, the canonicalization algorithm used (relaxed/relaxed is most common)

The MTA constructs the DNS lookup by combining the selector and domain: mail2026._domainkey.example.com. It fetches the TXT record at that address, extracts the p= tag (the public key), and verifies the body hash first, confirming the message body hasn't changed, then verifies the header hash using the same key.

What a DKIM Verification Failure Actually Means

A hard failure means the signature is present but invalid: the body or headers were modified after signing, the key was rotated without updating the selector, or the selector has been removed from DNS. A missing signature means there is no DKIM-Signature header at all, that's a neutral result, not a failure, but it leaves DMARC with one fewer alignment path to use.

Mailing list forwarding is the most common cause of DKIM body-hash failures in practice. When a mailing list manager appends a footer or rewrites the Subject line, the body hash stored in the bh= tag no longer matches the modified message body, and verification fails at the next hop, even though the original signature was valid when the message left the sender. This is documented in RFC 6376 §8.6 as a known interoperability problem. The only reliable workaround is for the mailing list to re-sign with its own DKIM key, which then creates a new d= domain that may not align with the original From.

DMARC Alignment Explained: Why a Passing SPF Can Still Fail DMARC

This is the most misunderstood part of the email authentication stack. The single most common misconception is "SPF passes, so DMARC passes." It's wrong because SPF and DMARC look at different domains.

DMARC alignment checks whether the domain authenticated by SPF (the RFC 5321 MAIL FROM domain) or the domain authenticated by DKIM (the d= tag) matches the RFC 5322 From header domain, the address the recipient sees in their mail client.

A classic failure scenario: a company sends marketing email through an ESP whose infrastructure uses its own envelope MAIL FROM domain (e.g. bounces.esp-provider.com) for bounce handling. SPF passes for esp-provider.com. But DMARC alignment fails because esp-provider.com does not match example.com, the brand's From domain. The message passes SPF and fails DMARC simultaneously.

The fix is either to have the ESP sign with a DKIM key whose d= tag matches example.com, or to set up a custom bounce domain under example.com so SPF alignment also passes.

Strict vs Relaxed Alignment Modes

DMARC supports two alignment modes, set separately for SPF (aspf=) and DKIM (adkim=):

  • Strict (s): the authenticated domain must exactly match the From domain. mail.example.com does not align with example.com.
  • Relaxed (r, the default): the authenticated domain and the From domain must share the same organizational domain. mail.example.com aligns with example.com under relaxed mode.

Relaxed alignment saves legitimate messages in subdomain-sending configurations. If your ESP sends from send.example.com and signs DKIM with d=send.example.com, relaxed alignment passes because both share example.com as the organizational domain. Strict mode fails that same message.

Reading the Authentication-Results Header as Evidence

The Authentication-Results header is written by the receiving MTA and records what happened. Dissecting the Authentication-Results block gives you the ground truth for any authentication dispute.

A typical block looks like this:

Authentication-Results: mail.receiver.example;
  spf=pass smtp.mailfrom=bounces.esp-provider.com;
  dkim=pass header.d=example.com;
  dmarc=pass header.from=example.com

Read it left to right: SPF passed for the envelope domain bounces.esp-provider.com, DKIM passed with d=example.com, and DMARC passed because the DKIM d= aligned with the From domain. If DKIM had been absent, SPF alignment would have failed, and dmarc=fail would appear instead, even with spf=pass on the line above.

DMARC Policy Enforcement and Aggregate Reports

DMARC policy is declared in the domain's DNS TXT record at _dmarc.example.com. The p= tag sets the policy:

  • p=none, take no action on failing messages; report only. Use this during initial deployment to observe without impacting delivery.
  • p=quarantine, route failing messages to the spam/junk folder.
  • p=reject, refuse failing messages at the SMTP level.

The pct= tag lets domain owners apply the policy to a percentage of failing messages, which enables gradual rollout, pct=10 applies the policy to 10% of failures while the rest are treated as none.

Interpreting DMARC Aggregate Report Data

Aggregate reports arrive as XML files attached to email, sent to the address in the rua= tag, typically once per day per reporting organization. Each report covers a 24-hour period and contains rows for each unique combination of source IP, From domain, and disposition.

Per the schema defined in RFC 9990, each record includes: the source IP, message count, SPF pass/fail result, DKIM pass/fail result, alignment outcome for each, and the policy disposition actually applied (none/quarantine/reject).

Use aggregate data to answer three questions before tightening policy:

  1. Which IPs are sending on behalf of your domain? Unexpected IPs are either unauthorized senders or infrastructure you forgot to authorize.
  2. Where is alignment failing? If SPF passes but alignment fails, you have an ESP using its own bounce domain. If DKIM fails, check for missing selectors or mailing list forwarding.
  3. What is the volume of failing messages? A small volume of failures from known forwarding paths (university mail forwarding, for example) looks very different from a spike originating from an unfamiliar IP range, the latter is a spoofing signal.

Moving from p=none to p=reject without reading aggregate reports first is the most reliable way to break legitimate mail flows you didn't know existed.

Email Authentication Failure Troubleshooting Playbook

Every authentication failure investigation starts in the same place: the Authentication-Results header of the received message. Pull the full header, find the block written by the final receiving MTA (identified by its authserv-id), and read the results for each method.

Diagnosing Failures from the Email Authentication Header

Work through this decision sequence:

SPF result is fail or softfail:

  • Is the sending IP listed in the SPF record? Check with a manual DNS TXT query or an SPF evaluation tool.
  • If the IP belongs to a legitimate ESP, add it via an include: mechanism or publish a custom bounce domain.
  • If the IP is unknown, treat it as a spoofing or compromised-account signal.

DKIM result is fail:

  • Is the selector (s= tag) still published in DNS? Rotated or deleted selectors cause hard failures for messages that were signed before the rotation.
  • Does the bh= hash mismatch suggest body modification? Suspect mailing list forwarding or a security gateway that rewrites content.
  • If the dkim= line is absent entirely, the message was never signed, check your MTA signing configuration.

DMARC result is fail despite SPF or DKIM passing:

  • This is an alignment failure. Compare the authenticated domain (envelope MAIL FROM or DKIM d=) against the RFC 5322 From domain.
  • If your ESP uses its own bounce domain, configure a subdomain alignment or ask the ESP to sign DKIM with your domain.
  • If you're using relaxed alignment and still failing, the organizational domains genuinely don't match, recheck your DNS and ESP configuration.

For the full delivery path and forged field analysis, including how to trace the Received chain and identify where evaluation occurred, the header forensics reference covers annotated specimens of every scenario above. When the Authentication-Results block alone doesn't resolve the failure, diagnosing delivery failures from raw headers provides the full step-by-step walkthrough from SMTP banner to final delivery verdict.

The email authentication stack is not three separate checklists. It is one layered system where each protocol's output feeds the next, and where the gap between the envelope and the visible From header is the exact seam that attackers exploit and DMARC was designed to seal. Reading the headers is how you know whether it's working.