← Glossary

Protocols & Acronyms

SPF (Sender Policy Framework)

Also: Sender Policy Framework · v=spf1 · SPF record · SPF -all · SPF ~all

Last reviewed:

In one sentence

SPF is a DNS TXT record that lists the servers allowed to send e-mail using your domain in the envelope sender, so a receiving server can reject mail from anywhere else.

Why it matters

SMTP has no built-in sender verification: any server can say MAIL FROM:<ceo@example.com>. SPF is the oldest of the three e-mail authentication mechanisms (with DKIM and DMARC) and the simplest: the owner of example.com publishes which IP addresses are allowed to do that, and the receiver checks the connecting IP against the list.

On its own it has a hole large enough that every phishing kit drives through it: SPF checks the envelope sender (the MAIL FROM / Return-Path), not the From: header the user sees. An attacker sends from their own domain with a valid SPF record and puts your CEO in the visible From. SPF passes. Only DMARC's alignment check closes that gap — which is why SPF is necessary but nowhere near sufficient.

How a record reads

example.com.  TXT  "v=spf1 ip4:203.0.113.10 ip4:203.0.113.0/28 include:_spf.google.com -all"
  • v=spf1 — the version tag, mandatory and first.
  • Mechanisms, evaluated left to right until one matches: ip4: / ip6: literal addresses or ranges; a and mx (the domain's A or MX hosts); include: to pull in another domain's record (your mail provider's); exists: and ptr (the latter deprecated).
  • Qualifiers on each mechanism: + pass (default), - fail, ~ softfail, ? neutral.
  • all — the catch-all at the end. -all says "everything else is a fail"; ~all says "probably not us, but don't be harsh". Receivers treat softfail leniently, so -all is the goal once you are sure the list is complete.

Two hard limits catch people out. A record may cause at most 10 DNS lookups in total (include, a, mx, redirect each count; nested includes count too) — exceed it and the result is permerror, which many receivers treat as no SPF at all. And a domain must have exactly one SPF record; two v=spf1 TXT records is also a permerror. Results are pass, fail, softfail, neutral, none, temperror, permerror, and they land in the Received-SPF and Authentication-Results headers.

Try it yourself hands-on

Your company moved from Google Workspace to Microsoft 365 last month and also sends invoices through a billing SaaS. Nobody touched DNS.

  1. Run the domain through the Email Security Checker. It fetches the SPF, DKIM and DMARC records and explains each verdict. A typical finding here: v=spf1 include:_spf.google.com ~all — still Google, softfail, so mail from Microsoft is currently softfailing and some of it is landing in spam.
  2. Build the replacement in the Email Auth Record Builder: add the Microsoft 365 include (spf.protection.outlook.com), the billing provider's include, and your own outbound relay as ip4:203.0.113.10. The builder estimates the DNS-lookup count under the record and warns when it passes ten. Choose -all.
  3. Before publishing, check the current record has only one v=spf1 entry with the DNS Record Lookup (TXT type). If the Google record is still there when you add the new one, you have two — and a permerror. Replace, don't add.
  4. Afterwards, send yourself a test message and paste its headers into the Email Header Analyzer: the Authentication-Results line should read spf=pass for the Microsoft IP.

Expected record: v=spf1 include:spf.protection.outlook.com include:_spf.billing-provider.example ip4:203.0.113.10 -all — three lookups, one record, hard fail.

Common misreadings

  • SPF breaks on forwarding. A forwarded message arrives from the forwarder's IP, which is not in your record. DKIM survives forwarding; SPF does not — another reason to run both.
  • Subdomains are not covered. example.com's record says nothing about mail.example.com. Subdomains that never send mail should get v=spf1 -all so they cannot be spoofed.
  • +all is worse than no record. It authorises the whole internet. It exists in more zones than you would think.