SPF (Sender Policy Framework) is the first line of defense in email authentication. It lets you declare in your DNS which servers are allowed to send email for your domain. Simple on the surface, it hides subtleties that trip up even experienced admins.
What Does SPF Actually Do?
When a receiving server gets an email from contact@yourdomain.com, it asks one question: “Is this server allowed to send for this domain?”
To answer, it checks the SPF record for yourdomain.com in DNS. That record lists the authorized IPs and servers.
Without SPF: any server can claim to send on your behalf. It’s an open door for spoofing.
With SPF: only servers you’ve explicitly authorized pass verification.
Anatomy of an SPF Record
An SPF record is a DNS TXT record placed at your domain’s root:
v=spf1 include:_spf.google.com include:spf.sendinblue.com ip4:203.0.113.50 -all
Let’s break it down:
| Element | Purpose |
|---|---|
v=spf1 | Protocol version (required, always first) |
include: | Authorizes servers declared in another domain’s SPF |
ip4: / ip6: | Authorizes a specific IP or CIDR block |
a | Authorizes the IP of your domain’s A record |
mx | Authorizes your MX server IPs |
redirect= | Redirects to another domain’s SPF (replaces everything) |
-all | Reject anything that doesn’t match (fail) |
~all | Mark as suspicious (softfail) |
?all | Neutral, no opinion |
Qualifiers
Each mechanism can be prefixed with a qualifier:
+(pass, default), authorized-(fail), rejected~(softfail), suspicious, accepted but flagged?(neutral), no indication
Best practice: always use -all in production. ~all is an acceptable compromise during rollout.
The 10 DNS Lookup Limit
This is the most common trap. RFC 7208 imposes a strict limit: an SPF record cannot trigger more than 10 DNS lookups.
Each include:, a, mx, redirect and exists counts as one lookup. ip4: and ip6: don’t count (they’re static values).
Example That Exceeds the Limit
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:spf.sendinblue.com include:servers.mcsv.net include:_spf.salesforce.com include:mail.zendesk.com include:spf.freshdesk.com -all
This looks correct, but each include: can itself contain nested include: directives. Google alone triggers 3-4 lookups. You easily exceed 10.
Result: permerror, the SPF is invalid, emails fail verification.
Solutions
- Replace
include:withip4:/ip6:for services with stable IPs - Use a “flattening” service that resolves includes to IPs at regular intervals
- Dedicate a subdomain per service (
marketing.yourdomain.comfor Mailchimp, etc.)
Check your SPF’s lookup count with our free SPF Checker, it shows every resolution in detail.
Step-by-Step Setup
1. Inventory Your Sending Sources
List every service that sends email for your domain:
- Your mail server (Exchange, Postfix, etc.)
- Marketing services (Mailchimp, Brevo, HubSpot…)
- Transactional services (SendGrid, SES, Postmark…)
- CRM (Salesforce, Pipedrive…)
- Support (Zendesk, Freshdesk…)
A free Sender Audit scan automatically shows all detected sources.
2. Build Your Record
For each service, find the SPF mechanism to add (usually in their docs). Assemble:
v=spf1 include:_spf.google.com include:spf.sendinblue.com ip4:203.0.113.50 -all
Free tool: our SPF Generator helps you build your record and automatically checks the 10 lookup limit.
3. Publish to DNS
Add a TXT record at your domain root (@). Important: there must be only one SPF record per domain. If one already exists, modify it rather than adding a second.
4. Test
Use the SPF Checker to validate:
- Syntax is correct
- Lookup count is ≤ 10
- All your services are included
- The final qualifier is
-all
SPF and DMARC: The Connection
SPF alone isn’t enough. For SPF to contribute to DMARC, the Return-Path domain (envelope) must align with the From: domain (visible header).
Many third-party services use their own domain as Return-Path, SPF passes but DMARC fails on SPF alignment. That’s why DKIM is essential as a complement.
To understand how everything fits together, read our DMARC guide.
Common Mistakes
- Multiple SPF records on the same domain → invalid
- Exceeding 10 lookups →
permerror - Using
+all→ authorizes everyone (worse than no SPF) - Forgetting a service → its emails fail SPF
- Not maintaining the record → discontinued services waste lookup slots
Go Further
- Configure DKIM, the other authentication pillar
- Configure DMARC, tie SPF and DKIM together
- Understanding Blacklists, when reputation goes wrong
- SPF Generator, build your record in a few clicks
- Free audit, check everything in 30 seconds
Questions? Join the community on Matrix.