SPF vs DKIM vs DMARC — what each does and how they work together
SPF, DKIM, and DMARC compared — what each protects against, how to set each one up, and how all three layer into a complete email deliverability posture.
SPF vs DKIM vs DMARC — what each does and how they work together
If you send email from your domain, three DNS-based standards determine whether your messages reach inboxes or get flagged as spam: SPF, DKIM, and DMARC. They are often mentioned together, but they protect against different threats and operate independently. Understanding what each one does — and where each one fails on its own — is the foundation of a solid email deliverability posture.
Why email deliverability matters
Email was designed without any built-in way to verify the sender. Anyone can put any address in the From: header of a message. Phishing campaigns exploit this by spoofing well-known brands; spam campaigns exploit it by hiding their true origin.
SPF, DKIM, and DMARC were created at different points in email's history to close different parts of that gap. None of the three is sufficient on its own. DMARC explicitly builds on SPF and DKIM — you cannot deploy DMARC meaningfully without having at least one of the other two working first.
SPF — Sender Policy Framework
SPF answers one question: is this IP address authorised to send email for this domain?
It works by having the domain owner publish a TXT record at the root of their domain that lists all the IP addresses and mail servers allowed to send on their behalf. When a receiving mail server gets a message claiming to be from example.com, it looks up the SPF record and checks whether the sending IP is in the list. If it is not, SPF fails.
SPF record syntax
A basic SPF record looks like this:
example.com. IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"Key parts:
| Part | Meaning |
|---|---|
v=spf1 | Required version tag |
include:_spf.google.com | Authorise all IPs in Google's SPF record |
include:sendgrid.net | Authorise all IPs in SendGrid's SPF record |
~all | Soft fail — unauthorised senders are marked suspicious but not rejected |
-all | Hard fail — unauthorised senders are rejected outright |
Common SPF pitfalls
Too many DNS lookups. SPF limits the total number of DNS lookups triggered by evaluating a record to 10. include: directives each count as a lookup, and they can chain further includes. Exceeding 10 lookups causes a permerror and SPF fails even for legitimate mail. Use an SPF flattening service if you have many senders.
Missing senders. Every service that sends email on behalf of your domain — transactional mail providers, marketing platforms, CRMs, billing systems — must be listed in your SPF record. A forgotten sender fails SPF and may fail DMARC.
+all at the end. +all means any server is authorised. It renders SPF completely ineffective. Always use ~all or -all.
Multiple SPF records. A domain must have exactly one SPF record. Multiple TXT records starting with v=spf1 cause a permerror. Merge them into one.
What SPF does not protect
SPF checks the envelope sender (the Return-Path or MAIL FROM address), not the From: header the recipient sees. A spammer can pass SPF while displaying a completely different From: address. This is why SPF alone is not enough.
DKIM — DomainKeys Identified Mail
DKIM answers a different question: was this message cryptographically signed by the domain it claims to be from?
The domain owner generates a public/private key pair. The private key is held by the mail server and used to sign each outgoing message. The public key is published as a DNS TXT record. When a receiving server gets the message, it looks up the public key and verifies the signature. If the signature is valid, it proves the message was sent by someone who controls the private key — and that the signed parts of the message have not been modified in transit.
DKIM record syntax
A DKIM public key is published at <selector>._domainkey.<domain>:
google._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9..."Key parts:
| Part | Meaning |
|---|---|
v=DKIM1 | Required version tag |
k=rsa | Key type (RSA is standard; Ed25519 is also supported) |
p=... | Base64-encoded public key |
The selector (here, google) is chosen by the signing mail service. Google uses google, SendGrid uses s1 or similar. You may have multiple DKIM selectors active simultaneously — one per sending provider.
Common DKIM pitfalls
Empty public key (p=) — a blank p= value means the key has been revoked. Messages signed with the corresponding private key will fail DKIM verification. This happens when a provider rotates keys without updating the DNS record.
Selector mismatch — the DKIM signature in the email header references a selector that does not exist in DNS, causing verification failure.
Forwarded messages — email forwarding services sometimes modify the message body (for example, appending a footer), which breaks the DKIM signature. This is a known limitation. DMARC's fallback to SPF alignment can compensate when DKIM fails due to forwarding.
Short key length — 1024-bit RSA keys are technically still accepted but considered weak. Use 2048-bit keys minimum.
What DKIM does not protect
DKIM proves the message came from someone with the private key and was not altered in transit. It does not prove the From: address matches the signing domain — the d= tag in the signature could be a different domain than the one in From:. This is where DMARC's alignment requirement closes the gap.
DMARC — Domain-based Message Authentication, Reporting, and Conformance
DMARC ties SPF and DKIM together and adds two things SPF and DKIM lack: policy enforcement and reporting.
It requires alignment — the authenticated domain must match the domain in the From: header the recipient sees. DMARC passes if at least one of the following is true:
- SPF passes and the
Return-Pathdomain aligns with theFrom:domain. - DKIM passes and the
d=tag in the signature aligns with theFrom:domain.
If neither passes with alignment, DMARC fails and your policy (p=) determines what happens:
| Policy | What receiving servers do |
|---|---|
p=none | Deliver normally, send you aggregate reports |
p=quarantine | Send to spam folder |
p=reject | Drop the message entirely |
DMARC record syntax
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; adkim=r; aspf=r"Key tags:
| Tag | Meaning |
|---|---|
v=DMARC1 | Required version tag |
p= | Policy: none, quarantine, or reject |
rua= | Address to receive aggregate reports (XML, daily) |
ruf= | Address to receive forensic (failure) reports |
pct= | Percentage of failing mail the policy applies to (default 100) |
adkim= | DKIM alignment: r relaxed (default) or s strict |
aspf= | SPF alignment: r relaxed (default) or s strict |
Common DMARC pitfalls
Skipping p=none. Publishing p=reject on day one breaks legitimate mail from any sender you forgot to configure. Always start with none, review aggregate reports for 2–4 weeks, then advance to quarantine, then reject.
No rua= address. Without a reporting address you have no visibility into what is passing and failing. Always include rua= even in none mode.
Forgetting the _dmarc. prefix. The record must be published at _dmarc.example.com, not at example.com.
Subdomains. DMARC applies to the exact From: domain. Subdomains inherit the parent policy unless you publish a separate record or use the sp= tag.
How all three layer together
SPF, DKIM, and DMARC each check a different thing. DMARC is the policy layer that makes the other two actionable:
Receiving server receives a message
│
├─ SPF check: is the sending IP authorised?
│ └─ SPF alignment: does Return-Path domain match From: domain?
│
├─ DKIM check: is the signature valid?
│ └─ DKIM alignment: does d= tag match From: domain?
│
└─ DMARC evaluation
├─ If SPF aligned pass → DMARC PASS
├─ If DKIM aligned pass → DMARC PASS
└─ If both fail → apply p= policySPF without DKIM and DMARC: Protects against IP-level abuse but cannot prevent From: header spoofing. Easy to break with forwarding.
DKIM without SPF and DMARC: Proves message integrity and signing domain but does not tie that to the From: header domain.
SPF + DKIM without DMARC: Both checks pass but nothing tells receiving servers what to do when they fail, and you get no reports.
SPF + DKIM + DMARC at p=reject: Complete protection. Receiving servers reject messages that fail both checks. You see aggregate reports showing any gaps.
Decision table
| Situation | Recommended action |
|---|---|
| No email auth at all | Publish SPF first, then DKIM, then DMARC p=none |
| SPF only | Add DKIM, then add DMARC p=none to start collecting reports |
DMARC at p=none for 2+ weeks | Review aggregate reports, fix gaps, move to p=quarantine |
DMARC at p=quarantine with clean reports | Move to p=reject |
| DMARC failing for a specific sender | Confirm the sender is in SPF and has DKIM set up with alignment |
Monitoring all three with DomainCare
DomainCare watches your SPF, DKIM, and DMARC records continuously and fires alerts when:
- A record goes missing or changes unexpectedly.
- The DMARC policy changes (including downgrades from
rejecttonone). - A DKIM selector is added, removed, or has key issues.
- SPF is present but missing the required
allmechanism.
See email deliverability for the full alert list, and fix a DMARC failure for a step-by-step diagnosis guide.
Monitor your email auth records
DomainCare alerts you the moment SPF, DKIM, or DMARC changes on your domain. Start your 30-day trial free.
Start free trial