DeliverabilityPublished 8 min read

SPF Flattening: How to Fix the 10-Lookup Limit Without Breaking Mail

AlexAlexFounder

SPF flattening replaces the include: entries in your SPF record with the IP addresses they point to, so the record needs fewer DNS lookups and stays under SPF's limit of 10. It works on the day you do it. Then a provider adds a new IP range, your flattened record doesn't have it, and real email from that provider starts failing SPF. Flatten only through a service that re-checks the includes and updates your record by itself, and try the four fixes below first: most domains over the limit get back under it without flattening anything.

Below: what counts toward the 10, how many lookups the common providers' includes actually cost (we measured them on 25 October 2026), a worked example of a record over the limit, and the fixes in the order we'd try them.

What is the SPF 10-lookup limit?

RFC 7208 caps an SPF check at 10 DNS lookups. Each of these terms costs one, and so does every term inside the records they pull in:

Costs a lookupFree
include:ip4:
aip6:
mxall
ptrexp=
exists:
redirect=

Go over 10 and the receiver must stop and return permerror. The RFC also says to stop after 2 "void" lookups, ones that find no record at all, which is what an include for a service that shut down or a typo in a domain gives you.

The count is recursive. include:mailgun.org looks like one entry, but that record includes two more, which include two more: five lookups for one line in your record.

What happens when SPF returns permerror?

The receiver treats SPF as failed for that email. Under DMARC, a message passes if either SPF or DKIM passes and aligns with the From domain, so a domain with working, aligned DKIM keeps passing DMARC through DKIM alone. That's why a broken SPF record can go unnoticed for months.

It still costs you. Any mail stream that isn't signed with your domain's DKIM key now fails DMARC, and receivers that look at SPF on its own see a domain with a broken record. Gmail and Yahoo ask bulk senders for working SPF and DKIM, and Outlook.com rejects high-volume mail that fails them with 550 5.7.515.

How many lookups does each provider's include cost?

We walked each provider's SPF include on 25 October 2026 and counted the lookups it costs once you add it to your record (the include itself plus everything nested in it). Providers change these records without notice, so recheck before you plan around a number.

ProviderIncludeLookups
Google Workspaceinclude:_spf.google.com1
Microsoft 365include:spf.protection.outlook.com1
Mailchimpinclude:servers.mcsv.net1
Mailchimp Transactional (Mandrill)include:spf.mandrillapp.com1
Amazon SESinclude:amazonses.com1
Brevoinclude:spf.brevo.com1
Zendeskinclude:mail.zendesk.com1
Zoho Mailinclude:zohomail.com2
SendGridinclude:sendgrid.net2
Salesforceinclude:_spf.salesforce.com2
Atlassian (Jira, Confluence)include:_spf.atlassian.net2
Mailguninclude:mailgun.org5
Freshdeskinclude:email.freshdesk.com7

Most providers keep their include flat and cheap. A few nest heavily: Freshdesk alone uses 7 of your 10.

What does a record over the limit look like?

A company on Google Workspace, with Mailgun for product email and Freshdesk for support:

v=spf1 include:_spf.google.com include:mailgun.org include:email.freshdesk.com ~all

Three entries, 13 lookups (1 + 5 + 7). Every receiver that checks SPF on this domain gets permerror, for all mail, including the Workspace mailboxes that would have passed on their own. Our SPF checker counts the lookups recursively and shows the total, so you see the 13 instead of the 3.

How do you fix too many SPF lookups without flattening?

In the order we'd try them:

1. Remove includes nobody uses

The most common cause. A record collects an include for every tool someone tried once: the old newsletter tool, the CRM trial, the help desk you left two years ago. Ask what still sends as your domain, and remove the rest. Also drop ptr (the RFC says not to use it) and any a or mx that only repeats servers already covered by an include.

2. Check which domain each service actually uses for SPF

SPF checks the envelope sender, the Return-Path address, not the From address the reader sees. Many sending services, once you authenticate your domain with them, send with a Return-Path on a subdomain they give you (something like em1234.example.com or mg.example.com) and handle SPF on that subdomain. For those, the include at your root does nothing. Look at the Return-Path header of an email the service sent: if it isn't your root domain, the root include can go.

3. Move senders to subdomains

Every domain and subdomain gets its own 10 lookups. Put support email on support.example.com and product email on mail.example.com, each with its own SPF record listing just that service. The root keeps only your mailboxes. In the example above, that's 1 lookup at the root, 7 on the support subdomain and 5 on the mail subdomain, all under the limit, and a problem with one stream stays on its own subdomain.

4. Then, if you must, flatten with a service

If you're still over after the first three, flattening is the remaining tool. Do it through a service that resolves the includes on a schedule and rewrites your record when a provider's IPs change. Copying IPs into the record by hand is the version that breaks: it's correct for exactly as long as no provider changes anything, and you find out it's stale from bounces, weeks later.

How do you flatten an SPF record by hand, if you have to?

Resolve each include to its ip4: and ip6: ranges, put those in the record in place of the include, and keep the includes you didn't flatten:

v=spf1 include:_spf.google.com ip4:141.193.32.0/23 ip4:159.135.140.80/29 ... ~all

Then put a reminder in your calendar to redo it every month, and redo it at once when a provider announces new ranges. Watch the length too: a TXT record over 255 characters has to be split into several strings, and a long flattened record can run into DNS answer size limits. If that reminder sounds like a job nobody will do, that's the argument for steps 1 to 3.

What about cold email domains?

Keep them simple. A domain you send cold email from should list only its mailbox provider:

v=spf1 include:_spf.google.com ~all

One lookup. Don't copy your main domain's record onto your cold domains: they don't send support or product email, and every extra include is one more thing that can break. If the cold domains are on Microsoft 365, it's include:spf.protection.outlook.com instead. The Gmail sending limits post covers how many mailboxes to put on each domain.

When this doesn't apply

A large organisation with dozens of services sending as one domain, each owned by a different team, won't get under 10 by tidying. That's a job for a managed SPF and DMARC service with reporting, and for moving streams onto subdomains over time. The fixes above are for the usual case: one domain, a handful of tools, and a few includes left over from tools nobody uses.

How Ballast checks it

Ballast's free domain check reads your SPF record, flags more than one SPF record (that's a permerror by itself), counts the lookups through every nested include against the limit of 10, and checks DKIM, DMARC and 9 blacklists in the same run. In the app, every sending domain is checked again each night, so an include that grows past the limit shows up as a failed check on the Domains page.

FAQ

What is SPF flattening?

Replacing the include: mechanisms in an SPF record with the IP addresses they resolve to, so the record needs fewer DNS lookups and stays under the limit of 10.

Is SPF flattening safe?

Only if something keeps it up to date. A flattened record is a copy of each provider's IP list on one day. When a provider adds IPs, mail from those IPs fails SPF until the record is updated. Use a service that updates it automatically, or don't flatten.

What counts toward the SPF lookup limit?

include, a, mx, ptr, exists and redirect, including every one inside the records you include. ip4, ip6 and all don't count.

What does SPF permerror mean?

The record couldn't be evaluated, most often because it needs more than 10 DNS lookups or the domain has two SPF records. Receivers treat it as an SPF failure.

Can I have two SPF records to get 20 lookups?

No. Two SPF records on one domain is a permerror on its own. Merge them into one record, or move some senders to a subdomain, which gets its own 10.

Does SPF fail if DKIM passes?

SPF and DKIM are checked separately. DMARC passes if either one passes and aligns with the From domain, so a working, aligned DKIM signature carries DMARC even when SPF is broken. Fix SPF anyway: not everything you send is signed with your domain's key.

Sources