SPF in DNS
The two firm rules helpdesk techs trip over: only one SPF per domain, and a 10-DNS-lookup limit on evaluation. Both violations silently turn SPF off.
SPF is the email-authentication record helpdesk techs touch most. Every M365, Google Workspace, CRM, or newsletter-platform onboarding adds something to SPF. Every mail provider migration changes it.
The two rules that trip techs up are subtle: one SPF sounds like one TXT, but the TXT layer allows multiple records while SPF itself only allows one starting with v=spf1. The 10-lookup limit isn’t visible in the SPF string; you have to count it. Both rules produce permerror outcomes that look like mail-auth working fine until you look at a receiver’s DMARC report.
What an SPF record looks like
| 1 | example.com. IN TXT "v=spf1 include:spf.protection.outlook.com include:_spf.salesforce.com -all" |
The mechanisms inside an SPF string are how it matches sending IPs: ip4:, ip4:.../24, a, mx, include:, exists:. In MSP work, include: is what you see most.
Rule 1: only one SPF per domain
Rule 2: the 10-DNS-lookup limit
SPF specifies a limit of 10 DNS lookups during evaluation. Each include:, a, mx, ptr, exists mechanism counts as one. Includes count recursively (an include whose target uses 5 lookups counts 5 against your limit, not 1).
How to count, roughly:
| Vendor include | Lookups it uses |
|---|---|
spf.protection.outlook.com (M365) | ~5 |
_spf.google.com (Google Workspace) | ~3 |
sendgrid.net (SendGrid) | ~4 |
You can quickly hit 10 by combining a few vendor includes. Over-limit = permerror = no SPF protection, even though the record is published.
The fix at the design level is SPF flattening: replacing include: mechanisms with explicit ip4: and ip6: ranges, which don’t count as lookups. Done manually it’s brittle (vendors change IPs); done with a managed SPF service it’s automatic. Either way, flattening is design territory and escalation, not helpdesk.
Practice: verify SPF before adding a sender
A client wants to add a new CRM that sends as their domain. Before you touch the record, check the current state.
When to escalate
This lesson stops at identify-and-apply. The following are escalation:
- SPF flattening when the lookup count exceeds 10.
- Adding a new sender when the SPF is already at or near the limit.
- DMARC enforcement showing SPF failures with no clear cause.
- Conflicts between policy terms (
~allvs-all) where the right choice depends on the client’s risk posture.
What to do with this
When asked to add a sender to a client’s SPF:
- Locate the existing TXT starting with
v=spf1. - Get the new include from the vendor’s setup docs.
- Merge into the existing TXT (don’t create a second one).
- Count lookups (MXToolbox’s SPF lookup count, EasyDMARC’s checker, or
digrecursively). - Publish and verify with
dig TXT example.com.
If the lookup count would exceed 10, stop and escalate.