Learn
SPF, DKIM & DMARC explained
A practical, developer-to-developer reference for the three email authentication checks — written for when you are testing the mail your own product sends and need to know exactly what a receiving server saw.
Last updated July 2026
When your application sends a signup confirmation, an OTP, or a password-reset link, the receiving mail server runs a set of checks before it decides where the message goes. Three of those checks — SPF, DKIM and DMARC — answer a single underlying question: is this message really authorized to come from the domain it claims to be from? Getting them right is what keeps your transactional mail out of the spam folder. This page explains what each one actually verifies, how they combine, and how to read the results while you test.
These are DNS-published, receiver-evaluated standards. Nothing here is specific to any one provider — they are defined in RFC 7208 (SPF), RFC 6376 (DKIM) and RFC 7489 (DMARC).
What is SPF
SPF — Sender Policy Framework — lets a domain owner declare which mail servers are allowed to send on the domain’s behalf. The domain publishes a DNS TXT record listing authorized IP addresses and includes. A receiving server looks up that record and checks whether the connecting server’s IP is permitted.
example.com. IN TXT "v=spf1 ip4:198.51.100.10 include:_spf.your-esp.com -all"A crucial detail: SPF authenticates the envelope sender — the MAIL FROM / Return-Path domain used during the SMTP transaction — not the From: address your recipient sees. Those two can differ (they routinely do when you send through an email provider), which is exactly why DMARC exists. The trailing -all means “anything not listed above should fail”; ~all is a softer “treat as suspicious”.
What is DKIM
DKIM — DomainKeys Identified Mail — attaches a cryptographic signature to each message. The sending server signs a canonicalized set of headers (and the body) with a private key and records the signature in a DKIM-Signature header. The corresponding public key is published in DNS under a selector.
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=mail2026;
h=from:to:subject:date; bh=...; b=iZ8q...signature...The receiver reads the domain (d=) and selector (s=), fetches the public key from mail2026._domainkey.example.com, and verifies the signature. A pass proves two things: the signing domain vouched for the message, and the signed headers and body weren’t altered in transit. Unlike SPF, DKIM survives forwarding, because it doesn’t depend on the connecting IP.
What is DMARC
DMARC — Domain-based Message Authentication, Reporting & Conformance — is the policy layer that ties SPF and DKIM to the visible From: domain. It is published as a TXT record at _dmarc.example.com.
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; adkim=s; aspf=s"DMARC does two things. First it sets a policy (p=) telling receivers what to do with mail that fails authentication:
none— take no action; monitor only. Useful while you roll out.quarantine— treat failing mail as suspicious (typically the spam folder).reject— refuse failing mail outright.
Second, it requests aggregate reports (rua=): receivers send back XML summaries of how your mail authenticated across the internet, which is how you discover a forgotten sending source before you tighten the policy.
How they work together: alignment
SPF and DKIM each authenticate a domain, but not necessarily the one your recipient reads in the From: field. DMARC closes that gap with alignment: it requires that a passing SPF or DKIM domain match the From: domain.
- SPF alignment — the
Return-Pathdomain that passed SPF matches theFrom:domain. - DKIM alignment — the
d=domain of a valid signature matches theFrom:domain.
DMARC passes if at least one of SPF or DKIM both passes and is aligned. Alignment can be strict (adkim=s / aspf=s, exact domain) or relaxed (the default, where a matching organizational domain such as mail.example.com vs example.com is enough). This is the single most common reason a message with a valid signature still fails DMARC: the signature passed, but its domain didn’t line up with the From: address.
How to read the results
A receiving server records what it found in an Authentication-Results header. Reading it is the fastest way to see, per message, whether your outbound mail actually authenticated:
Authentication-Results: mx.perenmail.com;
spf=pass (sender IP is 198.51.100.10) smtp.mailfrom=example.com;
dkim=pass header.d=example.com header.s=mail2026;
dmarc=pass (p=REJECT) header.from=example.comRead it field by field: spf=pass with an smtp.mailfrom that matches your domain, dkim=pass with the expected header.d and selector, and dmarc=pass against the header.from your recipient sees. A dmarc=fail next to a dkim=pass is the alignment problem described above.
This is where a private testing inbox helps. When you point your app’s signup, OTP or password-reset mail at a Perenmail address, the raw source & header view surfaces synthesized SPF, DKIM and DMARC auth results alongside the full RFC822 message, so you can debug your own outbound end-to-end — including the raw DKIM-Signature and Return-Path headers — without leaving the message you are inspecting. Raw source, headers and attachments are part of Personal+.
Keep reading
- Testing OTP & 2FA email — capture and verify one-time codes as they arrive.
- Frequently asked questions — how persistent, private inboxes work.
- Plans & pricing — what raw source, headers and attachments unlock.
Debug your outbound email against a real inbox
Point your app’s mail at a private, persistent Perenmail address and read the auth results yourself. Free to start, no credit card.