← glossary

$ authentication

What is SPF, and what does it actually check?

SPF is a DNS record listing which servers may send mail for your domain. It authenticates the envelope sender, which is not the address the recipient sees.

SPF — Sender Policy Framework, defined in RFC 7208 — is a DNS record that lists which servers are allowed to send mail for your domain. A receiving mail server reads it, compares it against the IP that just connected, and records a pass or a fail.

It answers exactly one question: is this machine allowed to send for this domain? It does not check the message, it does not check the sender’s intent, and — the part that trips people up — it does not check the address the recipient is shown.

What the record looks like

A single TXT record at the root of the domain:

yourapp.com.  IN  TXT  "v=spf1 include:_spf.provider.net ip4:203.0.113.10 -all"

Read left to right, it says: this is SPF version 1; whatever _spf.provider.net authorises is authorised here too; so is the single address 203.0.113.10; everything else fails.

The pieces:

  • v=spf1 — required first token. A domain may have only one SPF record. Two records is not “extra coverage”, it is a permerror, and a permerror is treated as no SPF at all.
  • Mechanismsinclude:, ip4:, ip6:, a, mx, exists:. Each either matches the connecting server or it does not.
  • all — the catch-all at the end, and the only part that expresses a policy.

-all versus ~all

The qualifier on all is the decision you are actually making:

MeaningEffect
-allHard failAnything not listed fails SPF
~allSoft failAnything not listed is suspicious but not rejected
?allNeutralNo opinion. Equivalent to no policy
+allPass everythingNever correct. Authorises the entire internet

~all exists for the transition period while you find every system that sends as your domain. Staying there permanently means you never finished. Once the list is right, -all is the record that says something.

The ten-lookup limit

SPF evaluation is capped at ten DNS lookups. include:, a, mx, ptr and exists: each cost one, and an include: that itself contains includes costs their lookups too. Exceed it and the result is permerror — the record stops working entirely, and nothing in your DNS looks wrong.

This is the most common way a working SPF record breaks: three or four vendors get added over two years, each contributing an include: that expands to two or three lookups, and the eleventh one silently disables authentication for the whole domain. Count them whenever you add a sender.

What SPF authenticates — and why that matters

SPF checks the envelope sender, also called MAIL FROM or Return-Path. That is the address bounces go back to. It is part of the SMTP conversation, not part of the message, and mail clients do not display it.

The address the recipient sees is the From: header, and SPF never looks at it.

Return-Path: bounces@mail.provider.net   ← SPF checks this
From:        noreply@yourapp.com         ← the recipient sees this

Those two can be completely different domains, with SPF passing, while the message still has nothing to do with you. Closing that gap is what DMARC alignment exists to do, and it is why SPF alone was never sufficient.

Where SPF breaks

  • Forwarding. When a recipient forwards to another address, the message arrives at the second server from a machine that was never in your record. SPF fails, correctly and uselessly. DKIM survives forwarding, which is one reason both exist.
  • Any new sender. Support desk, invoicing tool, CRM, a script on a server someone set up. Each needs adding, and nothing warns you when one is missing.
  • The lookup limit, as above.

Checking it

dig +short TXT yourapp.com | grep spf1

One record, under ten lookups, ending in -all or ~all for a reason you could explain. Then read an actual delivered message’s Authentication-Results header to see the verdict a real receiver reached, which is the only result that counts.

SPF is one of the three checks Pharos verifies before a domain may send. The deliverability page covers the other two and why alignment is the one that decides.