Frequently Asked Question
SPF limits the number of DNS-dependent terms that may be evaluated during a single SPF check. Under RFC 7208, the limit is 10. This protects receiving mail servers from excessive DNS traffic and deliberately or accidentally recursive SPF policies.
The limit applies to the complete evaluation path, including mechanisms referenced by other SPF records. It is not simply a limit of ten entries in the visible record.
What counts towards the limit
Each evaluated use of the following mechanisms or modifiers counts towards the ten-term limit:
includeamxptrexistsredirect
Lookups performed inside an included or redirected SPF policy also count towards the same total.
The following do not require DNS lookups and therefore do not count:
ip4ip6all
For example:
v=spf1 ip4:192.0.2.0/24 ip6:2001:db8::/32 -all
This contains no DNS-dependent terms.
DNS caching does not remove the SPF lookup cost. The limit concerns DNS-triggering SPF terms encountered during policy evaluation, not merely the number of unique network queries sent.
Why the example record is unsafe
The supplied policy begins with five top-level inclusions:
v=spf1 include:appriver.com include:freshdesk.com include:spf.protection.outlook.com include:spf-uk.emailsignatures365.com include:authsmtp.com -all
Those five include mechanisms can consume five terms by themselves. Each provider's record may then contain more include, a, mx, exists or redirect terms.
A possible evaluation path could therefore resemble:
1 include:appriver.com
2 nested lookup from appriver.com
3 another nested lookup from appriver.com
4 include:freshdesk.com
5 nested lookup from freshdesk.com
6 another nested lookup from freshdesk.com
7 include:spf.protection.outlook.com
8 first Microsoft nested include
9 second Microsoft nested include
10 third Microsoft nested include
11 another required term
The eleventh DNS-dependent term exceeds the limit. The exact count depends on the current provider records, the sender's IP address and the path evaluated, so it must be checked against live DNS rather than inferred solely from the visible record.
SPF evaluation is sequential
SPF mechanisms are evaluated from left to right and stop when a mechanism matches. Consequently:
- A message sent through the first provider might pass before later inclusions are evaluated.
- A message sent through the fifth provider may require all four preceding provider trees to be evaluated first.
- A sender that matches none of the providers may follow the longest path before reaching
-all. - A nested provider record can change at any time and unexpectedly push the total above ten.
Reordering providers may improve one sender's path, but it does not make an over-complex policy compliant for every sender.
PermError versus Fail
The standards-based result for exceeding the lookup limit is PermError, meaning that the domain has a permanent SPF configuration error. Some products, logs or management interfaces describe this as PermFail, but PermError is the SPF result defined by RFC 7208.
It is important to distinguish this from an ordinary SPF Fail:
Failoccurs when a valid policy reaches a matching-all.PermErroroccurs when the policy cannot be evaluated correctly, including when the ten-term limit is exceeded.- The presence of
-alldoes not convert a lookup-limit error into an ordinaryFail.
Receivers decide how to handle PermError. Depending on the MTA and its anti-spam policy, the message may be rejected, deferred, quarantined or assigned a higher spam score. It is therefore unsafe to assume that another authentication method will compensate for the broken SPF result.
Additional DNS limits
SPF also has protections against other forms of excessive DNS use:
- Implementations commonly limit void lookups—queries returning no data or a non-existent domain—to two. Exceeding the implementation's limit can produce
PermError. - An
mxmechanism must not cause more than ten address records to be examined. - The deprecated
ptrmechanism also has additional limits and should not be used in new policies.
These restrictions are separate from the overall ten-term limit.
Why the expanded address list does not prove compliance
A long list of IPv4 or IPv6 networks is not itself the DNS lookup count. For example, all of these are lookup-free when written directly in an SPF record:
ip4:40.92.0.0/15
ip4:40.107.0.0/16
ip6:2001:db8::/32
By contrast, one include may consume several terms because the included policy performs further DNS-dependent evaluations.
The repeated A values indicate that several mechanisms may ultimately resolve to the same address. Repeated results do not cancel their lookup cost. Each evaluated DNS-dependent SPF term still counts.
Why manually copying the expanded addresses is also a poor solution
Replacing every provider inclusion with the displayed IP addresses is often called SPF flattening. Although ip4 and ip6 mechanisms do not count towards the lookup limit, manually flattening this data is risky:
- Providers can add or remove sending networks without notice.
- A copied policy becomes stale and may reject legitimate mail or authorise obsolete infrastructure.
- Duplicated ranges increase record size without adding protection.
- Large records can encounter DNS message-size, resolver or management-platform limitations.
- Each individual DNS TXT character-string is limited to 255 octets, so long records require correct splitting and concatenation.
- Publishing multiple separate SPF TXT records beginning with
v=spf1is invalid and normally results inPermError.
A managed flattening service can monitor provider records and republish changes, but it introduces another dependency and must be monitored for stale data, DNS failures and record-size growth.
Recommended remediation
Inventory genuine outbound senders
Identify which services actually send mail using the domain in the SMTP envelope sender. Remove inclusions for retired, unused or incorrectly configured services.
Use provider-specific return-path subdomains
Configure third-party services to use separate envelope-sender subdomains where supported, for example:
bounce-support.example.com
bounce-marketing.example.com
bounce-notifications.example.com
Each subdomain can then publish a small SPF policy for the relevant provider:
v=spf1 include:provider.example -all
This is usually safer than placing every service in the organisational domain's SPF record.
Use the provider's documented SPF hostname
Do not copy guessed addresses or use an umbrella inclusion when the provider publishes a smaller, region-specific or product-specific policy.
Check nested policies, not just the visible record
Calculate the maximum evaluation path through every inclusion and redirect. A policy should retain spare capacity because providers can alter their records.
Do not attempt to bypass the limit with more includes
Moving mechanisms into a locally controlled record does not reset the counter:
v=spf1 include:spf1.example.com include:spf2.example.com -all
The includes and all DNS-dependent terms below them remain part of the same ten-term evaluation.
Avoid multiple SPF records
A domain must publish one applicable SPF policy. Separate TXT records such as the following are invalid:
v=spf1 include:provider-one.example -all
v=spf1 include:provider-two.example -all
Use DKIM and DMARC as well as SPF
Third-party platforms should use DKIM with the organisation's domain wherever possible. DMARC can then authenticate aligned DKIM even where SPF alignment is unsuitable. This does not make an invalid SPF record acceptable, but it reduces dependence on SPF for every service.
Retest after every change
Check the domain against live DNS and test the worst-case sender path, particularly senders represented by mechanisms near the end of the policy. Testing only a sender that matches the first inclusion can conceal an over-limit path.
The robust design is therefore to keep each SPF policy small, remove unnecessary providers, separate unrelated mail streams onto suitable return-path subdomains, and avoid relying on a manually maintained dump of provider IP addresses.
