Explainers

SPF, DKIM and DMARC, Explained

Three DNS records decide whether your mail is trusted or quietly binned. What SPF, DKIM and DMARC each check, how alignment ties them together, the mistakes that break them, and how to check your own domain.

The order confirmations stop arriving. Nothing bounces, and nothing shows up in a log. Customers just write in asking whether their order went through, and the answer turns out to be sitting in their spam folder, where it has been going for a week.

When this happens, the cause is usually one of three DNS records: SPF, DKIM and DMARC. Between them they decide whether a receiving mail server believes your message really came from you. This post covers what each one checks, how they fit together, and the mistakes that break them.

Why mail needs proving at all

Email was designed in an era when everyone on the network knew each other. The protocol that carries it, SMTP, lets the sending server claim any sender address it likes. Nothing in the original design stops a server anywhere from sending mail that says it comes from your domain.

So receivers have to check, and to understand how, you need to know that a message carries two different "from" addresses:

  • The envelope sender, also called the Return-Path or MAIL FROM. The sending servers use it to route bounces. People never see it.
  • The header From, the address shown in the mail client. This is the one people trust, and the one spammers forge.

Keep that distinction in mind. Most of the confusion around these three records comes from which address each one checks.

SPF: which servers may send for you

SPF, the Sender Policy Framework, is a TXT record on your domain that lists the servers allowed to send mail for it:

example.com.  TXT  "v=spf1 include:_spf.google.com include:spf.mtasv.net ~all"

When a message arrives, the receiver takes the domain of the envelope sender, looks up its SPF record, and checks whether the connecting server's IP address is on the list. The include: entries pull in the lists published by your providers, so you do not have to track their IP addresses yourself.

The record ends with what to do about everyone else. -all says mail from anywhere else fails. ~all says it soft-fails, meaning it is suspicious but not to be rejected on this alone. Once DMARC is in place, ~all is a perfectly good choice, because DMARC makes the final decision anyway.

There are two rules that catch people out:

  1. One SPF record per domain. If you publish two v=spf1 records, the result is a permanent error, which receivers usually treat as a failure. This happens all the time, because every new tool's setup guide says "add this SPF record" instead of "add this include to your existing one".
  2. At most ten DNS lookups. The standard, RFC 7208, caps the number of mechanisms that need a DNS query (include, a, mx, ptr, exists and redirect) at ten, counting everything nested inside every include. Go over the limit and SPF fails outright. ip4 and ip6 entries cost nothing, which is why SPF-flattening tools replace includes with raw addresses. The catch is that someone then has to keep those addresses current.

SPF has one structural weakness. It checks the envelope sender, not the address people see, so on its own it does nothing to stop someone forging your header From. It also breaks when mail is forwarded, because the forwarding server is not on your list.

DKIM: a signature on the message itself

DKIM, DomainKeys Identified Mail, takes a different approach. Instead of vouching for servers, it signs the message. The sending server hashes the body and a chosen set of headers, signs the result with a private key, and adds a DKIM-Signature header:

DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=pm2026;
    h=from:to:subject:date; bh=...; b=...

The d= tag names the signing domain and s= names the selector. The receiver fetches the public key from pm2026._domainkey.example.com and checks the signature. If anything covered by it changed in transit, the check fails.

Selectors are what let you run several providers at once, each with its own key, and rotate keys without downtime: publish a new selector, switch signing to it, then retire the old one. Many providers ask you to add a CNAME instead of the key itself, so they can rotate keys without you touching DNS again. Use 2048-bit keys. The 1024-bit keys you still see in old setups are past their safe age.

Because the signature travels with the message, DKIM usually survives forwarding. Mailing lists that add a footer or rewrite the subject line do break it.

DMARC: tying it to the address people see

Neither SPF nor DKIM on its own says anything about the header From. DMARC closes that gap with one idea, alignment. A message passes DMARC when SPF or DKIM passes and the domain it passed for matches the domain in the visible From address.

By default the match is relaxed, meaning the same organisational domain is enough, so mail.example.com aligns with example.com. You can make it strict with aspf=s and adkim=s, but few senders need to.

The record lives at _dmarc under your domain:

_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

p= is the policy, meaning what you ask receivers to do with mail that fails:

Policy What receivers do with failing mail
p=none Deliver it as normal, and include it in reports
p=quarantine Treat it as suspicious, which usually means the spam folder
p=reject Refuse it during the SMTP conversation

rua= is where the aggregate reports go. These are daily XML files from Google, Microsoft, Yahoo and others, listing every source that sent mail claiming to be you, with pass and fail counts. They are unreadable by hand and invaluable through any of the free or cheap report parsers. They are also how you find the invoicing tool someone signed up for last year that has been sending as you ever since.

sp= sets a separate policy for subdomains. Without it they inherit p=.

The 2026 update

In May 2026, after years of drafts, the IETF published the revised DMARC specification as RFC 9989, with reporting split out into RFC 9990 and RFC 9991. It makes DMARC a standards-track protocol for the first time. For most domains, nothing breaks. Existing v=DMARC1 records keep working. The pct tag, which applied a policy to a percentage of mail, is gone, replaced by a simpler t=y flag for a policy you are still testing. A new np= tag sets a policy for subdomains that do not exist, which is where a lot of spoofing hides.

Why receivers now insist

For years this was best practice that only large senders bothered with. That changed in February 2024, when Gmail and Yahoo started requiring bulk senders to have SPF, DKIM and a DMARC record, with alignment. Gmail draws the line at around 5,000 messages a day to its users, and requires every sender below it to have at least SPF or DKIM. Microsoft followed in May 2025 for Outlook.com, Hotmail and Live addresses, and non-compliant bulk mail there is rejected outright with a 550 5.7.15 error instead of landing in junk.

A small shop sending a few hundred order confirmations a day is below those thresholds. It still gets judged by the same filters, and unauthenticated mail from a small domain with no sending history is exactly what those filters are built to distrust.

A rollout that does not break your own mail

Going straight to p=reject is how companies discover, the hard way, that their helpdesk was sending password resets from an unauthenticated server. The safe order is:

  1. List every service that sends as your domain. Your mailbox provider, transactional email, newsletters, helpdesk, CRM, invoicing, the store platform, and the contact form on the website.
  2. Fix SPF. Keep one record, include each sender, and stay under ten lookups.
  3. Turn on DKIM for your own domain in every service. This is the step people skip. Many providers sign with their own domain by default, which passes DKIM but does not align with yours. Look for "custom domain", "domain authentication" or "sender domain" in each one's settings.
  4. Publish DMARC with p=none and a rua address.
  5. Read the reports for two to four weeks. Every legitimate source should show as aligned. Chase down whatever is not.
  6. Move to p=quarantine, then p=reject.

The mistakes I see most

A second SPF record, added by a new tool's setup wizard. Both stop working.

The ten-lookup limit, reached quietly as providers add includes inside their own includes. Nothing changed in your record and SPF started failing anyway.

A provider signing with its own domain. DKIM passes and DMARC fails, and the reports are the only place you will see it.

-all on a domain whose mail gets forwarded, combined with no DKIM. Forwarded mail fails SPF, has nothing else to pass on, and disappears.

Unprotected parked domains. A domain that never sends mail is a gift to spoofers unless you say so explicitly. Three records close it off:

example.net.         TXT  "v=spf1 -all"
_dmarc.example.net.  TXT  "v=DMARC1; p=reject;"
example.net.         MX   0 .

The last one is a null MX, which tells the world the domain accepts no mail at all.

Checking your own domain

You do not need a paid tool to see what you have published:

dig +short TXT example.com | grep spf1
dig +short TXT _dmarc.example.com
dig +short TXT pm2026._domainkey.example.com

The DKIM selector is the awkward one, because you cannot list selectors from DNS. The easiest way to find yours is to send yourself a message from each service and read the headers. In Gmail, "Show original" gives you a summary of SPF, DKIM and DMARC results at the top, and the Authentication-Results header shows the full detail, including the s= and d= that signed it.

Authentication is not reputation

Passing all three proves who sent a message. It does not prove anyone wants it. A fully authenticated domain can still end up on a domain blacklist like Spamhaus DBL, SURBL or URIBL, which list domains that appear in spam. Once it is listed, the mail it sends and the links pointing to it are filtered no matter how clean the DNS looks.

Authentication does help you stay off those lists. A domain at p=reject is much harder to use in someone else's spam run, because forged mail claiming to be from it gets refused at the door.

Barkme does not audit your SPF or DMARC records. It watches for the listing: every verified domain is checked daily against Spamhaus DBL, SURBL and URIBL, as well as the DNS filters that block sites for visitors. You get one alert when the domain is listed, naming the lists, and another when it clears. When your domain lands on a blacklist covers how listings happen and how to get off them.

For the DNS basics underneath all of this, see how DNS works. For the other email that must never land in spam, the registrar's renewal reminder, see the expiry dates that take websites down. The how it works page and the F.A.Q cover what Barkme checks and how often.

Put this into practice

Barkme watches your sites around the clock and barks the moment one goes down. Free plan, no card required.

Try Barkme free