Most SPF records are subtly broken. The 10-lookup limit, multiple records, +all, and the alignment trap what's actually wrong with your SPF setup.
What SPF Actually Does (And What It Does Not)
SPF was designed in 2003, formalized as RFC 4408 in 2006, and superseded by RFC 7208 in 2014. The mechanism is straightforward: a domain owner publishes a TXT record listing the IP addresses and hostnames authorized to send mail on behalf of the domain. When a receiving server gets a message claiming to be from that domain, it checks the connecting IP against the published list. Authorized? Pass. Not authorized? Fail.
The trap is in what SPF checks. SPF authenticates the envelope sender (also called the Return-Path or MAIL FROM), not the visible From header in the email. These are usually different. A message from newsletter@yourbrand.com typically has an envelope sender like bounces+xyz@mail.espprovider.com. SPF checks the envelope sender's domain. The user sees yourbrand.com. The spam filter checks espprovider.com.
This disconnect is the single biggest source of confusion in email authentication. SPF can pass while the message is, from the user's perspective, completely spoofed. That is not a bug it is the protocol working as designed. SPF was never meant to authenticate the visible sender. DMARC was.
For SPF to provide meaningful protection, it needs to be configured correctly and aligned with the visible domain through DMARC. SPF alone is necessary but not sufficient.
Anatomy of a Working SPF Record
A typical SPF record looks like this:
Tag by tag:
v=spf1- Version. Always this exact value. There is no v=spf2.include:_spf.google.com- Authorize all IPs that Google's SPF record authorizes. Recursive lookup.include:mailgun.org- Same, for Mailgun.ip4:203.0.113.0/24- Authorize this specific IP range.-all- Reject anything not matched by the above.
The mechanisms (include, ip4, ip6, a, mx, ptr, exists) are evaluated left to right. The first match wins. The final all mechanism is a catch-all for anything that did not match.
Qualifiers prefix mechanisms and tell the receiver what to do on a match:
+(default, often omitted) - Pass-- Fail (hard fail; reject)~- SoftFail (mark as suspicious but accept)?- Neutral (no opinion)
The qualifier on all is the most consequential character in the entire record. I will come back to this.
The Four Mistakes Senders Actually Make
These are the SPF failures I see in customer audits, in order of how often I encounter them.
Mistake 1: Exceeding the 10-DNS-Lookup Limit
This is the most common failure mode and the hardest to diagnose because it produces no visible error in normal operation.
RFC 7208 caps the number of DNS lookups during SPF evaluation at 10. Each include:, a:, mx:, ptr:, and exists: mechanism counts as a lookup. Includes are recursive if include:_spf.google.com itself contains four includes, those four count too. The math compounds quickly.
What happens when you exceed the limit:
The receiver returns permerror. Per the RFC, permerror is treated as if SPF were not configured at all. Some receivers go further and treat it as a fail signal. Either way: your authentication breaks, and your only signal is occasional bounces or quiet inbox placement degradation.
A real example I have audited:
A B2B SaaS company had this record:
v=spf1 include:_spf.google.com include:spf.mailgun.org include:_spf.salesforce.com include:sendgrid.net include:_spf.atlassian.net include:spf.protection.outlook.com include:_spf.intercom.io include:mail.zendesk.com -all
Eight includes. Looks reasonable. In practice:
_spf.google.comresolved to 4 lookupsspf.mailgun.orgresolved to 2 lookups_spf.salesforce.comresolved to 5 lookups- ... and so on
Total: 23 lookups. The record was producing permerror on every message. The company had been live with this configuration for two years and only noticed when their Microsoft 365 deliverability collapsed and their support tickets spiked.
How to fix it:
- Audit with a tool. DMARC Analyzer's SPF surveyor and easydmarc.com/tools/spf-record-checker both count lookups recursively. Run your record through one. If you see 10 or more, you are broken.
- Use SPF flattening as a last resort. Services like Scott Kitterman's tools or commercial flatteners resolve all includes into a static list of IPs. This eliminates lookups entirely but creates a maintenance burden the record must be updated every time any of your providers changes their IPs. For most senders, flattening trades one problem for another.
- Cull aggressively. The cleaner fix is to remove sources you do not actually use. The B2B SaaS example above had
include:entries for tools they had stopped using months earlier. Audit your sending sources, confirm which ones are live, remove the rest. - Move third-party tools to subdomains. If
transactional.yourbrand.comonly sends through your ESP, the SPF record on that subdomain only needsinclude:for the ESP. The parent domain stays lean.
Mistake 2: Multiple SPF Records on the Same Domain
You can publish multiple TXT records for various purposes domain verification for Google Workspace, MX-related records, Microsoft 365 ownership challenges. You can only have one record that begins with v=spf1.
Per RFC 7208, if a receiver finds two or more SPF records, the result is permerror. Same as the lookup limit failure: silent break.
This happens often when a new tool's onboarding wizard says "add this TXT record to your DNS" and the admin pastes it in without checking that another SPF record already exists. Suddenly you have:
Both fail.
How to fix it:
Merge into a single record:
There is no upper limit on length within a single record (well below DNS limits in practice), so consolidation is always possible.
To check: query your domain with dig:
If you see more than one line, you have a problem.
Mistake 3: The Wrong all Qualifier
The qualifier on all is the most consequential character in your SPF record. Most domains are configured wrong.
+all -Pass everything. This authorizes the entire internet to send mail as your domain. I am not exaggerating. If you have +all, anyone can spoof you and SPF will say "yes, that is legitimate." I see this in production multiple times per year. It is almost always a copy-paste error from a documentation example or a leftover from initial testing.
?all - Neutral. The receiver should treat the message as if no SPF record existed. This is functionally equivalent to having no record at all, except it now consumes lookup budget for any domain that includes you.
~all - SoftFail. The message is marked as suspicious but typically still delivered. SoftFail is the conservative choice for domains in initial rollout where you are unsure if you have catalogued all sending sources.
-all - Fail. The message should be rejected or marked as spam. This is the correct setting for any domain whose SPF record is complete and accurate.
The migration path:
Start with ~all while you are still discovering sending sources via DMARC aggregate reports. Once you are confident every legitimate sender is in your record, move to -all. Most senders never make that move and stay at ~all permanently, which weakens the protection but is not catastrophic.
If you find +all or ?all in your record, fix it today. There is no production scenario where either is correct.
Mistake 4: Treating SPF as Self-Sufficient
SPF passes for the envelope sender. The user sees the From header. These are usually different domains. Without DMARC enforcing alignment between the two, SPF authenticates a domain the user never sees.
Concrete scenario:
You configure SPF correctly for yourbrand.com. Your ESP sends through bounces.espprovider.com. SPF passes for espprovider.com. The user sees newsletter@yourbrand.com. A spam filter sees:
- Visible From:
yourbrand.com - Authenticated domain:
espprovider.com - Match: No
Without DMARC, the receiver still has to make a judgment call. Reputation, content signals, prior recipient behavior all of these come into play. SPF helped, but only marginally.
With DMARC and proper alignment, the picture changes:
- Visible From:
yourbrand.com - Authenticated domain:
espprovider.com - DMARC alignment check: Fails (different organizational domains)
- DMARC verdict: Fail
That is when you fix it: configure your ESP to use a custom Return-Path under your domain (e.g., bounces.yourbrand.com). Now SPF authenticates yourbrand.com directly. DMARC alignment passes. The visible domain matches the authenticated domain.
This is not optional anymore for bulk senders. As of Yahoo and Gmail's February 2024 requirements, alignment is mandatory.
What a Production-Ready SPF Record Looks Like
For a typical mid-sized sender using two or three ESPs plus a Google Workspace setup:
- One Workspace include, one ESP include, one specific IP for an in-house relay, hard fail on everything else.
- Lookup count: well under 10.
- One record, not three.
-all, not+all.
Adapt to your sending mix. The discipline is the same.
For a sender with many third-party tools (CRM, support, billing, calendar, etc.), the better pattern is subdomain delegation. Keep the parent domain clean, route each tool through a dedicated subdomain with its own SPF record. The subdomain SPF only needs to authorize that one tool. Lookup budget stays comfortable.
How to Test Your SPF Configuration
Three checks, all free:
- Resolution check. Run
dig +short TXT yourbrand.comand verify you see exactly one record starting withv=spf1. - Lookup count. Use easydmarc.com/tools/spf-record-checker or any SPF surveyor. Confirm you are below 10 lookups.
- Live send test. Send a test message to a Gmail address. Open "Show original." Confirm
SPF: PASSand that the authenticated domain matches your visible From-domain (alignment).
If all three checks pass, your SPF is functional. If you also have DMARC at p=quarantine or p=reject with aggregate reporting enabled, you have meaningful protection.
Frequently Asked Questions
Does SPF protect my domain from being spoofed?
What is the difference between SPF and DMARC?
Do I need SPF if I use DKIM?
Can I have an SPF record longer than 255 characters?
What happens if my SPF record returns permerror?
Should my subdomains have their own SPF records?
Is ptr: mechanism safe to use?
Key Takeaways
- SPF authenticates the envelope sender, not the visible From header. Without DMARC alignment, SPF alone does not prevent spoofing.
- The 10-DNS-lookup limit is the silent killer. Audit your record annually and after every new tool integration.
- Multiple v=spf1 records on the same domain produce permerror and silently break authentication.
- The qualifier on all is the most important character in your record. -all for established setups, ~all during initial rollout, never +all or ?all.
- SPF is necessary but not sufficient. Pair it with DKIM and DMARC for actual authentication.
- Test with dig, an SPF surveyor, and a live send check. All three should pass.
- Subdomain delegation is the cleanest path for senders with many third-party tools. Keep the parent domain lean.
Many SPF records in production are subtly broken. Yours probably is too. Fix it before someone else notices and exploits it.


