Big protection. Even on the free plan. Meet your new DNS home
KumoDNS
Blog › SPF, DKIM and DMARC, in plain terms

SPF, DKIM and DMARC, in plain terms

30 September 2026 · Jimmy

SPF may this server send? DKIM was it altered? DMARC does it align with the visible From? p=none · report p=quarantine p=reject start at the top, move down

Three DNS records decide whether your mail arrives or lands in spam. They are usually explained together, which makes them sound like one system. They are not — they check different things, and understanding which does what is the difference between fixing a problem and guessing at it.

SPF: which servers may send

An SPF record lists the servers allowed to send mail using your domain in the envelope sender.

example.com.  IN  TXT  "v=spf1 include:_spf.google.com include:sendgrid.net -all"

The receiving server looks at the connecting IP and asks whether SPF permits it. -all at the end means nothing else is authorised.

The trap: ten lookups. Each include: costs a DNS lookup, and the limit is ten for the whole evaluation, counting nested includes. Exceed it and the result is permerror, which many receivers treat as a failure — so adding one more provider can break mail from every provider. Check the count whenever you add one.

Counting it by hand is the hard part, because most of the cost is not in the record you wrote — it is inside a provider's include, two levels down, and it goes up when they edit their record. The SPF checker expands the whole chain and shows which terms spent the ten. It also counts the limit almost nobody knows about: a lookup that resolves to nothing is a void lookup, you are allowed only two, and a record can sit comfortably under ten and still permerror because three vendors in it have since shut down.

SPF breaks on forwarding. If someone forwards your mail, the forwarding server is now the sender, and it is not in your SPF. This is not a misconfiguration, it is a limitation of the design, and it is the reason DKIM exists.

-all (hard fail) versus ~all (soft fail) is the other decision. Start with ~all while you are still finding senders you forgot about; move to -all when you are confident.

DKIM: was this message altered

DKIM signs the message cryptographically. The private key lives with your mail provider; the public key is a TXT record at a selector under your domain:

selector1._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIGfMA0..."

The receiver fetches the key named in the message's signature header and verifies it. If it verifies, the message is unaltered and genuinely from a system holding your key.

DKIM survives forwarding, because the signature travels with the message rather than describing the connection. That is precisely the gap SPF leaves.

The selector exists so you can have several keys at once — one per provider, and a new one alongside the old during a rotation. Providers usually give you the record to publish.

DMARC: what to do when the first two fail

DMARC ties them together and adds the two things neither has: alignment and a policy.

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

Alignment is the part that makes DMARC worth having. SPF and DKIM can both pass for a domain that is not the one in the visible From: header — which is what a convincing forgery looks like. DMARC requires that a passing check belongs to the same domain the recipient sees.

The policy says what to do when nothing aligns:

  • p=none — do nothing, but report. This is where you start.
  • p=quarantine — treat as suspicious.
  • p=reject — refuse outright.

rua= is the reason to publish DMARC on day one, even at p=none. Receivers send you aggregate reports listing every source sending as your domain — including systems you had forgotten and anyone forging you. You cannot safely move to p=reject without having read them.

The order to do this in

Doing these in the wrong order is how people reject their own mail.

  1. Publish DMARC at p=none with rua=. It changes nothing and starts the reports.
  2. Read the reports for a few weeks. Find every legitimate sender — the CRM, the invoicing system, the monitoring alerts, the thing marketing signed up for.
  3. Fix SPF and DKIM so every one of those passes and aligns. This is the real work.
  4. Move to p=quarantine, and watch.
  5. Then p=reject, once the reports are clean.

The step people skip is the second. Going straight to p=reject is how a company discovers its payroll notifications came from a system nobody documented — by them disappearing.

Quick checks

dig +short TXT example.com
dig +short TXT selector1._domainkey.example.com
dig +short TXT _dmarc.example.com

Two things to watch for. Only one SPF record per domain — two v=spf1 records is a permerror, and it happens when a second provider's instructions are followed literally rather than merged. And DMARC lives at _dmarc, not at the apex; a DMARC policy published at the root does nothing at all.

dig shows you the record; it does not follow the includes or add up what they cost. For that use the SPF checker, or the mail check if you want SPF, DKIM, DMARC and MX read in one go.

All three are TXT records, available on every KumoDNS plan including Free.

Need somewhere to put these records?

KumoDNS hosts one zone free — no card, no time limit.

Create a free account

More from the blog

Top