Article Email

SPF, DKIM and DMARC explained

Three DNS records that between them answer one question: is this message really from you? Here is what each proves.

Updated 9 min read Intermediate

Email was designed in an era when everybody on the network was trusted, and it shows: the "From" address on a message is simply a line of text the sender types. Nothing in the original protocol stops anyone claiming to be anyone.

SPF, DKIM and DMARC are the three patches the industry bolted on afterwards. They are all DNS records — nothing is installed on your server — and between them they answer one question a receiving mail server needs answered: is this message really from the domain it claims?

Get them wrong and your legitimate mail lands in spam. Leave them out entirely and anyone can send mail that appears to come from your domain.

SPF — who is allowed to send

An SPF record is a public list of the servers permitted to send email for your domain. A receiving server compares the sending server against that list.

v=spf1 include:_spf.example-host.com include:_spf.google.com ~all

Reading that left to right: this is an SPF record; mail from the servers listed by our host is legitimate; so is mail from Google's servers; and anything else is suspicious.

EndingMeansUse when
~allSoft fail — treat others as suspectNormal. Safe while you are still finding every service that sends for you
-allHard fail — reject others outrightOnce you are certain the list is complete
+allAllow anybodyNever. It explicitly authorises the whole internet to send as you
One SPF record per domain, and no more

Two SPF records is a configuration error, and receiving servers treat it as a permanent failure rather than picking one. If you add a service, extend the record you have with another include: — do not publish a second record. There is also a hard limit of ten DNS lookups; a record with more include: statements than that fails for everyone.

What SPF does not do: it checks the envelope sender, which is not the "From" address a person reads. On its own it can be passed by a message displaying somebody else's address in the client. That gap is what DMARC exists to close.

DKIM — proof the message was not altered

DKIM signs each outgoing message cryptographically. Your mail server holds a private key; a matching public key is published in your DNS. The receiving server fetches the public key, checks the signature, and learns two things: the message really came from your domain, and nothing in the signed part changed on the way.

The DNS record is a TXT record at a selector name, and looks like this:

selector1._domainkey.yourdomain.com   TXT   "v=DKIM1; k=rsa; p=MIGfMA0GCSq..."

You do not compose this yourself — your mail provider generates the key pair and gives you the record to publish. The only thing to be careful about is copying the long p= value completely and without introducing line breaks or spaces, which is the usual reason a freshly added DKIM record fails validation.

DMARC — what to do when the other two fail

SPF and DKIM each produce a verdict. Neither says what a receiving server should do about a bad verdict, and neither tells you it happened. DMARC does both.

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

Two parts matter. p= is the policy — what you are asking receivers to do with mail that fails. rua= is where aggregate reports are sent, and it is the genuinely valuable half: those reports tell you who is sending mail as your domain, including services you had forgotten about and anyone forging you.

DMARC also adds the check SPF alone cannot make: it requires the authenticated domain to match the visible From address. That is what stops a message that technically passes SPF from displaying your address to the reader.

Roll the policy out in stages

  1. Start at p=none

    Nothing is rejected. Reports start arriving. Leave it here for a few weeks and read them — the point is to discover every legitimate sender before you start blocking.

  2. Move to p=quarantine

    Failing mail goes to spam rather than the inbox. Do this once the reports show your real senders all passing.

  3. Finish at p=reject

    Failing mail is refused outright. This is the setting that actually stops people forging your domain, and it is safe only once you are sure nothing legitimate fails.

Do not start at p=reject

Almost every organisation has a sender it has forgotten: an invoicing system, a booking form, a newsletter tool, a CRM. Publishing a reject policy before you have found them all silently destroys that mail — and because it is rejected at the receiving end, nobody tells you.

The order to do this in

  1. List every service that sends mail as your domain. Website forms, newsletter tools, invoicing, helpdesk, CRM. This step takes the longest and skipping it causes every subsequent problem.
  2. Publish SPF covering all of them, ending in ~all.
  3. Enable DKIM with your mail provider and publish the key they give you.
  4. Publish DMARC at p=none with a reporting address.
  5. Read reports for a few weeks, fix whatever is failing, then tighten the policy.

Step-by-step instructions for each record are in setting up SPF, setting up DKIM and setting up DMARC.

Does this fix mail going to spam?

It removes the most common technical reason for it, and it is a prerequisite for the large mailbox providers, several of which now require authentication for bulk senders. But authentication proves who you are — it does not make you welcome. Reputation, content and whether people actually want your mail all still count. Why your emails go to spam covers the rest.

Related reading