Developers

SPF, DKIM and DMARC: what each record does and how to set it up

The three DNS records a receiving mail server checks against your domain Mail from your domain SPF Which servers may send DKIM Signature proves it is intact DMARC What to do when a check fails A check must pass and match the From: domain

SPF, DKIM and DMARC are three TXT records in your domain’s DNS that together let a receiving mail server decide whether a message claiming to come from you actually did. They are separate mechanisms that answer separate questions, they fail in different ways, and the order you add them in matters more than most setup guides admit.

What do SPF, DKIM and DMARC actually prove?

Three different claims, checked independently.

SPF is a list of the servers allowed to send mail for your domain. The receiver takes the sending server’s IP address and asks whether your domain authorised it.

DKIM is a cryptographic signature over the message. The sending server signs a set of headers and the body with a private key; the receiver fetches the matching public key from your DNS and verifies that nothing it signed has changed in transit.

DMARC is the policy on top. It tells receivers what to do when the first two fail, and it adds a requirement neither of them makes on its own: the domain that SPF or DKIM authenticated has to match the domain a human sees in the From: header. That last part is the entire point. Without it, anyone can pass SPF for a domain they control while putting your address in the From: line.

What goes in an SPF record?

One TXT record at the domain apex, starting with v=spf1 and ending in an all mechanism:

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

Four things break SPF in practice.

Two records. A domain may publish exactly one v=spf1 record. Publish two and evaluation returns permerror, which counts as a failure. Two providers means one record with two include: terms.

The ten-lookup limit. Each include:, a, mx, ptr and exists term costs a DNS lookup, and nested includes count too. Past ten, the result is permerror. Long chains of vendor includes hit this quietly.

The wrong all. -all tells receivers to reject anything from an unlisted server. ~all is a softfail, which most receivers accept and tag. Start at ~all and tighten once reports are clean.

Forwarding. SPF authenticates the envelope sender, in the Return-Path, not the From: header. A forwarded message arrives from the forwarder’s server, which your record does not list, so SPF fails through no fault of the record.

How does DKIM signing work?

The sending server generates a key pair. The private half stays on the server; the public half goes into DNS under a selector you choose:

sel1._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

On the way out, the server hashes the body and a chosen set of headers, signs the hash, and attaches a DKIM-Signature header naming the domain in d= and the selector in s=. The receiver reads those two fields, fetches <selector>._domainkey.<domain>, and verifies.

The selector exists so you can hold more than one key at a time, which is what makes rotation possible: publish the new key, switch signing to it, then remove the old record once nothing is signed with it.

DKIM survives forwarding, which SPF does not, because the signature travels with the message. It breaks when something rewrites the signed parts in transit — mailing lists that append a footer or edit the subject are the common case.

What does a DMARC policy decide?

A TXT record on the _dmarc subdomain:

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

p is the instruction to receivers: none to do nothing beyond reporting, quarantine to treat failures as suspicious, reject to refuse them outright. rua is where aggregate reports go, and it is the reason to publish the record long before you enforce anything.

DMARC passes when SPF passes and its domain aligns with the From: domain, or when DKIM passes and its d= aligns. One is enough. Alignment defaults to relaxed, meaning the organizational domains have to match — mail.example.com aligns with example.com. Strict alignment requires them to be identical.

In what order should you add them?

MX first, then SPF and DKIM, then DMARC at p=none, then enforcement — and the gap between the last two is measured in weeks, not minutes.

  1. MX. Mail has to arrive before authenticating it means anything.
  2. SPF and DKIM together. Both are additive and neither rejects mail on its own.
  3. DMARC at p=none with an rua address. Nothing changes for recipients; reports start arriving.
  4. Read the reports. They will name senders you forgot: the invoicing system, the CRM, the monitoring alerts, whatever the marketing team signed up for. Every one of those either gets added to SPF, starts signing with DKIM, or stops using your domain.
  5. p=quarantine, then p=reject. Move once the reports show only failures you recognise as forgeries.

Publishing p=reject before reading reports is the standard way to make legitimate mail disappear. The failures are silent to you and invisible to the sender.

How do you check the records are right?

Query them the way a receiver does:

dig +short MX example.com
dig +short TXT example.com
dig +short TXT sel1._domainkey.example.com
dig +short TXT _dmarc.example.com

Then send a real message to an account elsewhere and read the Authentication-Results header it arrives with. That header is the receiver’s own verdict on all three checks, including alignment, which no amount of reading your own DNS will tell you:

Authentication-Results: mx.receiver.example;
  spf=pass smtp.mailfrom=example.com;
  dkim=pass header.d=example.com;
  dmarc=pass header.from=example.com

Watch header.d and header.from in particular. When those disagree, DMARC fails no matter how green the other lines look.

What do these records not do?

They authenticate a domain. They say nothing about the content of a message, and nothing about encryption.

A message can pass all three checks and still be a fraud, as long as it is an honest fraud about which domain sent it — attackers register lookalike domains and publish perfect records for them. Nor do these records encrypt anything: transport security is TLS between hops, and whether the message is encrypted where it comes to rest is a separate question with a separate answer.

What they do fix is the class of forgery that puts your exact domain in the From: line. That was free before, and after p=reject it is not.

Frequently asked questions

Do I need all three of SPF, DKIM and DMARC?

You need SPF and DKIM for mail to be trusted at the big receivers, and DMARC to tell them what to do when a check fails. DMARC on its own does nothing: it passes only when SPF or DKIM already passes and the domain it authenticated matches the domain in the From: header. Google and Yahoo have required all three from bulk senders since February 2024.

What happens if I publish two SPF records?

SPF evaluation returns permerror and the check fails, even though both records are individually valid. A domain may publish exactly one TXT record starting with v=spf1. If you use two providers, merge them into one record with two include: terms.

Why does DMARC fail when SPF passes?

Because DMARC also requires alignment. SPF authenticates the envelope sender in the Return-Path, which for forwarded or relayed mail is often a different domain from the one in the visible From: header. When those two domains do not match, SPF passes on its own terms and still fails DMARC. DKIM signing with your own domain is the usual fix.

How long do changes to these records take to apply?

As long as the TTL on the record you replaced, because resolvers keep serving the cached copy until it expires. A TTL of 3600 means up to an hour. Lower the TTL a day before a planned change and raise it again afterwards.