All posts

Common SPF Mistakes: What We Found in 696 Real Company Domains

··8 min read

The most common SPF mistakes in real company domains are going over the 10-lookup limit, using includes that point nowhere, and leaving SPF out entirely. In 696 company domains we checked on 2 October 2026, 16 records needed more than 10 DNS lookups, a permanent error, and 120 more were at 8 to 10.

Most SPF guides list mistakes from experience. This one counts them. We evaluated every SPF record recursively, the way a receiving server does, and tallied what we found.

How we measured

Two samples, 696 domains, every include followed to the bottom.

  • 200 SaaS companies: the largest by listed team size among companies tagged SaaS in Y Combinator's public company directory (B2B, active or public), read from the open mirror at yc-oss.github.io.
  • 496 S&P 500 companies: the constituents in Wikipedia's "List of S&P 500 companies", with each company's official website domain taken from Wikidata.

For each domain we fetched the apex TXT records with dnspython against public resolvers (1.1.1.1, 8.8.8.8, 9.9.9.9) and kept those starting v=spf1. We then walked the record per RFC 7208, counting one DNS lookup for each include, a, mx, ptr and exists mechanism and each redirect, recursively through every nested include. We also counted void lookups, meaning names that returned no record. Run at 03:44 UTC on 2 October 2026.

One complication: 209 of the S&P 500 records (43.8%) use SPF macros, such as Proofpoint's %{ir}.%{v}.%{d}.spf.has.pphosted.com. A macro is expanded per message using the sender's IP, so it cannot be fully evaluated without one. We counted each macro include as one lookup and went no further, which makes our lookup totals for those domains a lower bound.

The results at a glance

Check SaaS (n=200) S&P 500 (n=496)
Publishes SPF 196 (98.0%) 477 (96.2%)
No SPF record 4 19
No SPF but has an MX record 2 12
Two or more SPF records 0 0
More than 10 lookups (permerror) 5 11
Exactly 10 lookups 4 35
8 to 10 lookups 20 100
Median lookups 4 3
Maximum lookups 18 18
Uses ptr (deprecated) 0 1

Percentages below use the domains that publish SPF as the base.

Mistake 1: more than 10 DNS lookups

This was the most common hard failure: 5 SaaS records (2.6%) and 11 S&P 500 records (2.3%) need more than 10 lookups.

RFC 7208, section 4.6.4, caps the number of lookup-causing terms at 10 for the whole evaluation, nested includes included. Past that, the result is permerror, which does not count as an SPF pass when a receiver evaluates DMARC. Two of the eleven S&P 500 domains over the limit use macros, so their true totals are higher than we could count.

The near-misses matter as much. 20 SaaS domains and 100 S&P 500 domains sat at 8 to 10 lookups. Adding one more sending tool, or a provider quietly adding a nested include to its own record, pushes them over.

Lookups SaaS domains S&P 500 domains
0 1 11
1–3 85 240
4–7 85 115
8–10 20 100
11+ 5 11

How a record reaches 18 lookups

The worst SaaS record in the sample looked like this (account ID replaced):

v=spf1 include:usb._netblocks.mimecast.com include:spf.protection.outlook.com
  include:<id>.spf05.hubspotemail.net include:zcsend.in include:zoho.com
  include:Zohoforms.com include:zcsend.in ~all

Three separate problems are visible:

  1. include:zoho.com includes the provider's whole corporate SPF record. That record itself includes four more names. Providers publish a dedicated include for customers; the company domain is not it.
  2. include:Zohoforms.com adds seven further includes for the same reason.
  3. include:zcsend.in appears twice. Each occurrence is counted.

Including a provider's own domain instead of its documented SPF include was the single fastest route to the limit that we saw. If an include in your record is just a company's homepage domain, check that provider's documentation for the right one.

Mistake 2: includes that point at nothing

Two SaaS domains had includes that resolve to no SPF record at all.

The first had four includes that returned NXDOMAIN when we queried them:

v=spf1 mx a include:_spf.google.com include:servers.mcsv.net
  include:spf.hubspotemail.net include:spf.apollo.io include:spf.mailmodo.com
  include:spf.loops.so include:spf.instantly.ai -all

spf.apollo.io, spf.mailmodo.com, spf.loops.so and spf.instantly.ai did not exist in DNS when we checked. They read like guesses at what each tool's include might be called. Under RFC 7208 an include whose target has no SPF record produces a permanent error, and the RFC separately recommends failing after more than two void lookups. This record has four. The tools it was meant to authorise get no protection from it, and the error can take down the whole record.

The second was a copy-and-paste error. The last include ran into the qualifier with no space:

v=spf1 include:mail.zendesk.com include:dc-<id>._spfm.<domain>-all

That makes -all part of a hostname that does not exist, and leaves the record with no all mechanism at all. That was the only SaaS record in the sample without one. The same domain also had an orphaned TXT record containing just include:...spf03.hubspotemail.net, which is not part of any SPF record and does nothing. It looks like a second include that was meant to be pasted into the first record.

Mistake 3: no SPF at all

4 SaaS and 19 S&P 500 domains publish no SPF record. Of those, 2 SaaS and 12 S&P 500 domains do have MX records, so they receive mail on that domain.

A domain without SPF is not automatically broken. If all its mail is DKIM-signed and aligned, DMARC can still pass. But Google's sender guidelines require SPF and DKIM for bulk senders, and a domain that sends nothing should still publish v=spf1 -all so that spoofers get a definite failure.

The ~all versus -all question

SaaS companies overwhelmingly end with ~all; the S&P 500 is split down the middle.

Final qualifier SaaS Share S&P 500 Share
~all (softfail) 146 74.5% 248 52.0%
-all (fail) 46 23.5% 228 47.8%
?all (neutral) 3 1.5% 1 0.2%
No all 1 0.5% 0 0%

Nobody in either sample used +all, which authorises the whole internet.

This is a genuine judgement call rather than a mistake. With DMARC at quarantine or reject, the DMARC policy decides what happens to unauthenticated mail, and many operators prefer ~all so that forwarded mail that breaks SPF still has a chance to pass on DKIM. ?all is the one we would change: it says "no opinion", which is barely different from having no SPF record.

What everyone includes

88.3% of the SaaS companies include _spf.google.com. That is 173 of 196, consistent with what we found in our MX record study: SaaS companies run on Google Workspace.

Most common top-level includes SaaS S&P 500
_spf.google.com 173 17
spf.protection.outlook.com 10 157
Proofpoint hosted SPF (macro) 0 137
mail.zendesk.com 43 22
amazonses.com 32 21
sendgrid.net 27 14
mailgun.org 25 14
_spf.salesforce.com 24 57
mktomail.com (Marketo) 11 28

The S&P 500 pattern is different. Large companies increasingly hand SPF to a managed service that answers with a macro, which keeps the record short and dodges the lookup limit, and 209 of them do so.

How to check your own record

Count your lookups before a receiver does.

  1. Fetch your record: dig +short TXT yourdomain.com | grep spf1
  2. Check there is exactly one line beginning v=spf1. Two records is a permanent error.
  3. For each include:, fetch that name's TXT record too and count its includes, recursively. Add one for each a, mx, ptr, exists and redirect.
  4. If the total is over 10, remove includes for tools you no longer use, replace any provider homepage domains with their documented include, and remove duplicates.
  5. Query every include target once. Any NXDOMAIN is a void lookup and an include that authorises nothing.

The SPF checker does the recursive count for you, and the SPF generator builds a clean record. If you are over the limit, our guide to fixing "too many DNS lookups" covers the options, including SPF flattening and its trade-offs.

Limitations

  • Macro records are undercounted. 43.8% of S&P 500 records use macros we could not expand without a sending IP.
  • Apex domain only. Many companies send marketing mail from subdomains with their own SPF records, which we did not check.
  • Website domain, not mail domain. We used each company's website domain, which is not always the domain it sends from.
  • One snapshot. Records change, and so do the provider records they include.
  • Not a random sample. Both groups are large, well-resourced companies. Smaller organisations very likely make these mistakes more often.

The short version

  • 16 of 673 published SPF records needed more than 10 lookups and therefore fail with permerror.
  • Another 120 were at 8 to 10, one new tool away from the same failure.
  • The fastest way over the limit is including a provider's company domain instead of its SPF include.
  • Guessed include names produce void lookups. Copy includes from each provider's documentation.
  • ~all is the SaaS default (74.5%). The S&P 500 is split almost evenly between ~all and -all.

Raw data: download the full dataset as CSV. It is free to reuse with a link back to this page.

Common questions

What is the most common SPF mistake?

In our October 2026 measurement it was exceeding the 10 DNS lookup limit, usually by including a whole provider domain rather than its SPF include. Five of 196 SaaS records and 11 of 477 S&P 500 records needed more than 10 lookups, which RFC 7208 says makes the SPF result a permanent error.

Should SPF end in ~all or -all?

Both are common and both work with DMARC. In our sample 74.5% of SaaS companies used ~all (softfail) and 23.5% used -all (fail); the S&P 500 was close to an even split. With DMARC enforcing, the DMARC policy decides what happens to failing mail, so the choice matters less than keeping the include list accurate.

How many SPF lookups is too many?

More than 10. RFC 7208 counts every include, a, mx, ptr and exists mechanism and every redirect, including those nested inside other includes, and caps the total at 10. A record that needs 11 returns permerror. In our sample, 20 SaaS domains were already at 8 to 10.

What happens if an SPF include points at a domain that doesn't exist?

Each such include is a 'void lookup', and RFC 7208 recommends failing the check after more than two. It also means the include contributes no authorised servers. We found one SaaS company with four includes pointing at names that returned NXDOMAIN, apparently guessed rather than copied from each provider's documentation.

Verify unlimited addresses for $29.99/month

Real SMTP mailbox checks. No credits, no per-email fees.

Get Started