Rigcheck

Guides

SPF too many DNS lookups: how to fix the 10-lookup limit

If a DMARC report, a mail log or a checker told you your SPF record has too many DNS lookups, your SPF record is broken for every message you send. Receivers stop evaluating it partway through and return a PermError, which most of them treat the same as a failure.

The frustrating part is that nothing tells you when it happens. It usually starts the day someone adds one more tool, like a newsletter service or a help desk, and everything still looks fine from your side.

This guide explains what counts toward the limit and how to get back under it, starting with the fixes that carry the least risk.

Not sure where you stand? Rigcheck counts every lookup in your SPF record, including the ones hidden inside nested includes.

Check your domain

What the 10-lookup limit is

When a receiving server checks SPF, it may need to run extra DNS queries to resolve parts of your record. The SPF standard (RFC 7208) caps those queries at 10 per check. The cap covers the whole evaluation, including every record your includes pull in, not just the terms you can see in your own record.

What counts

TermCounts toward 10?
include:Yes, plus everything inside the included record
a, mxYes, one each
exists:, redirect=Yes, one each
ptrYes, and it's deprecated, so remove it
ip4:, ip6:, allNo

Nesting is what catches people out. A single include: for a large provider can cost several lookups, because that provider's record includes other records of its own. Four or five services can easily add up to more than 10.

There's a second, lesser-known limit: no more than two "void" lookups, meaning queries that return nothing. An include pointing at a misspelled or retired domain uses one of those, so old typos can break SPF too.

What happens when you go over

The receiver stops evaluating and returns PermError. SPF doesn't pass for any message, including mail from services listed before the limit was reached.

Whether that sends your mail to spam depends on DKIM. DMARC passes if either SPF or DKIM passes and matches your domain. If every service that sends for you signs with DKIM for your domain, DMARC can still pass while SPF is broken. If any service relies on SPF alone, its mail will fail DMARC, and with a p=quarantine or p=reject policy, it goes to spam or bounces.

So the first thing to do is make sure DKIM is turned on in every service that sends for you. That protects you while you fix SPF.

Five ways to fix it

These are ordered from safest to riskiest. Most domains get back under 10 with the first two.

1. Remove services you no longer use

SPF records collect leftovers: the email tool you tried two years ago, the old hosting company, a CRM you switched away from. Go through each include: and ask whether that service still sends email as your domain today. If nobody can say yes, remove it.

2. Check whether each include is actually needed

This one surprises people. SPF isn't checked against the From address your recipients see. It's checked against the hidden Return-Path (also called the envelope sender or bounce address).

Many email services use their own domain for the Return-Path unless you set up a custom one. In that case, the receiver checks their SPF record, and the include in yours does nothing except use up lookups. Services that do use a custom Return-Path usually put it on a subdomain, like bounces.yourdomain.com, which has its own SPF record anyway.

To check, send yourself a message from each service and view the original message or headers. Look for the Return-Path line, or for smtp.mailfrom= in the Authentication-Results header. If that domain isn't your main domain, that service's include probably doesn't belong in your main SPF record. Remove it, then test again and confirm SPF and DMARC still pass.

3. Replace a and mx with IP addresses

The a and mx terms each cost a lookup. If they point at your own servers with fixed IP addresses, list those addresses with ip4: or ip6: instead, which cost nothing. Skip this if the servers are managed by someone else and their addresses might change.

Also check whether you need mx at all. It authorizes your incoming mail servers to send, which only matters if those same servers send outgoing mail. With Google Workspace or Microsoft 365, the provider's include already covers that.

4. Move bulk email to a subdomain

Every domain and subdomain gets its own 10-lookup budget. Sending newsletters and marketing email from something like news.yourdomain.com takes those services out of your main record entirely. It also protects your main domain's reputation if a campaign gets spam complaints. Most email services let you choose the sending subdomain when you authenticate your domain.

5. Flatten the record, carefully

"Flattening" means replacing includes with the IP addresses they resolve to, since ip4: and ip6: don't count. It works, but providers change their IP ranges without telling you. A record you flatten by hand will quietly go stale and start failing for some of your mail.

Only flatten with a service that re-checks the provider records and updates yours automatically, and treat it as a last resort after trying the steps above.

An example

Here's a typical record that has grown over time. It needs more than 10 lookups once the nested includes are counted:

v=spf1 a mx include:_spf.google.com include:servers.mcsv.net include:sendgrid.net include:mail.zendesk.com include:_spf.salesforce.com include:oldhost.example ~all

After working through the steps, this domain found that the old host was gone, Mailchimp used its own Return-Path, and the mail servers in a and mx didn't send any outgoing mail. Marketing email from Salesforce moved to a subdomain. The result:

v=spf1 include:_spf.google.com include:sendgrid.net include:mail.zendesk.com ~all

Three includes, comfortably under the limit, with room to add a service later.

Things that don't fix it

  • Adding a second SPF record. A domain can only have one. Two records make SPF fail outright, which is worse than the problem you started with.
  • Splitting the record into multiple strings. Long TXT records are split into chunks automatically. That's about length, not lookups, and doesn't change the count.
  • Switching ~all to -all or ?all. The ending decides what happens to unlisted servers. It has nothing to do with the lookup count.

After you change the record

DNS changes usually take effect within minutes, occasionally a few hours. Once you've saved the new record:

  1. Run your domain through Rigcheck and confirm the lookup count is 10 or fewer. Results are cached for five minutes, so wait a little before checking again.
  2. Send a test message from each service that sends for you and check that SPF, DKIM and DMARC pass in the headers.
  3. If you have DMARC reporting set up, watch the next few days of reports for anything that starts failing.

Check your SPF lookup count now. It takes a few seconds and shows exactly which parts of your record need fixing.

Check your domain

More guides