Updated 10 hours ago
SPF (Sender Policy Framework) lets domain owners answer a simple question: "Who is allowed to send email as us?"
When your mail server receives a message claiming to be from user@example.com, it can check example.com's DNS records to see if the sending server is on the guest list. If not, something's wrong.
The Problem SPF Solves
SMTP was designed for a world that trusted everyone. The From header is just text—anyone can type anything. When a server connects and announces "I'm sending mail from user@trusted.com," there's no handshake, no credential check, no proof. Spammers discovered this decades ago.
SPF adds the missing verification. Domain owners publish their authorized mail servers in DNS. Receiving servers check incoming mail against these published records. It's a guest list for email.
How SPF Works
1. Email arrives: A mail server receives a message from IP 203.0.113.50 claiming to be from sender@example.com.
2. DNS lookup: The receiving server queries example.com's SPF record:
3. Check the list: Is 203.0.113.50 authorized? The record says: accept the 203.0.113.0/24 range, accept whatever Google authorizes, reject everyone else.
4. Verdict: SPF returns pass, fail, softfail, neutral, or none. The receiving server acts accordingly.
Reading SPF Records
SPF records are DNS TXT records. Here's how to read them:
v=spf1 — "This is an SPF record, version 1." Must come first.
ip4:203.0.113.0/24 — "Accept mail from IPs 203.0.113.0 through 203.0.113.255."
include:_spf.google.com — "Also accept whatever Google's SPF record authorizes." This is how you delegate to cloud email providers.
-all — "Reject everyone else." The minus means hard fail.
Mechanisms
Mechanisms are the entries on your guest list:
ip4 / ip6 — Specific IP addresses or ranges:
a — Whatever IPs the domain's A record points to:
mx — Whatever servers handle incoming mail for this domain:
include — Delegate to another domain's SPF policy:
Qualifiers
Qualifiers go before mechanisms and specify what to do on a match:
+ (pass) — Authorized. This is the default if you don't specify.
- (fail) — Explicitly unauthorized. Reject the message.
~ (softfail) — Probably unauthorized, but don't reject outright. Mark it suspicious.
? (neutral) — No opinion. Up to you.
The critical one is all at the end, which catches everything that didn't match earlier:
Real-World Examples
Simple setup (just your mail server):
Only servers in your MX records can send mail.
Google Workspace:
Google handles your email.
Office 365:
Microsoft handles your email.
Multiple sources (common in real organizations):
Your mail servers, Google, SendGrid, and that one legacy server at 203.0.113.50.
Testing mode:
Softfail while you're still figuring out who sends mail for you. Switch to -all once you're confident.
The Limitations
10 DNS lookups:
SPF evaluation is limited to 10 DNS lookups total. include, mx, a, and exists mechanisms all count. This prevents abuse but constrains complex configurations. Exceeding the limit causes permanent failure.
Forwarding breaks everything: When someone forwards your email, the forwarding server sends it from its own IP—which isn't on your guest list. The forwarded message fails SPF.
This is genuinely absurd: SPF can't distinguish between "helpful forwarding" and "malicious spoofing." They look identical. Solutions exist (SRS, ARC), but forwarding remains SPF's Achilles heel.
Envelope vs. header: SPF checks the envelope sender (the SMTP MAIL FROM), not the From header users see in their email client. These can differ. A message can pass SPF while displaying a completely different sender.
This is why SPF alone isn't enough. DMARC addresses this gap.
SPF Results
Pass: Sender is on the list.
Fail: Sender is explicitly not on the list (-all, -ip4, etc.).
Softfail: Sender is probably not on the list (~all). Suspicious but not damning.
Neutral: Domain makes no assertion (?all).
None: Domain has no SPF record.
TempError: DNS hiccup. Try again.
PermError: SPF record is broken (syntax error, exceeded lookup limit).
Checking SPF Records
Online tools like MXToolbox and dmarcian will parse the record and show you the full tree of includes.
Deployment Checklist
-
Inventory your senders. Who sends email as your domain? Your mail server, marketing platforms, CRM, monitoring tools, that vendor from 2019 you forgot about.
-
Start with softfail. Deploy with
~allto catch misconfigurations without rejecting legitimate mail. -
Monitor with DMARC. DMARC reports show you who's sending as your domain and whether they're passing SPF.
-
Switch to hard fail. Once you're confident in your list, change
~allto-all. -
Watch the lookup count. Each
includecascades. Flatten where possible. -
One record per domain. Multiple SPF records cause permanent errors. Consolidate everything into one.
SPF Is Necessary but Not Sufficient
SPF solves one problem: verifying that a server is authorized to send mail for a domain. It doesn't verify the message content, doesn't prevent the display-name tricks that fool humans, and breaks on forwarding.
For real protection, combine SPF with DKIM (cryptographic message signing) and DMARC (policy alignment). Together, they form the modern email authentication stack.
Frequently Asked Questions About SPF
Was this page helpful?