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;aandmx(the domain's A or MX hosts);include:to pull in another domain's record (your mail provider's);exists:andptr(the latter deprecated). - Qualifiers on each mechanism:
+pass (default),-fail,~softfail,?neutral. all— the catch-all at the end.-allsays "everything else is a fail";~allsays "probably not us, but don't be harsh". Receivers treat softfail leniently, so-allis 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.
- 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. - 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 asip4:203.0.113.10. The builder estimates the DNS-lookup count under the record and warns when it passes ten. Choose-all. - Before publishing, check the current record has only one
v=spf1entry 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. - Afterwards, send yourself a test message and paste its headers into the Email Header Analyzer: the
Authentication-Resultsline should readspf=passfor 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 aboutmail.example.com. Subdomains that never send mail should getv=spf1 -allso they cannot be spoofed. +allis worse than no record. It authorises the whole internet. It exists in more zones than you would think.