The rule

SPF lists the servers allowed to send mail as your domain. To keep a single SPF check from turning into dozens of DNS queries, the standard caps the work. RFC 7208, section 4.6.4:

The following terms cause DNS queries: the "include", "a", "mx", "ptr", and "exists" mechanisms, and the "redirect" modifier. SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation [...] If this limit is exceeded, the implementation MUST return "permerror".

Three things trip people up:

  1. Nested lookups count. An include: costs one lookup, plus every lookup inside the record it points to, all the way down.
  2. ip4:, ip6: and all are free. So is exp=. Only the six terms above count.
  3. Lookups that find nothing have their own limit. The same section says receivers "SHOULD limit 'void lookups' to two", meaning lookups that return no record at all. An include for a service you cancelled, whose record is gone, counts against both limits.

What happens when you go over

A receiver checks the terms left to right and stops at the first one that matches the sending server. Mail from a service listed early may still pass. Mail from any service whose turn comes after the 10th lookup gets a permanent error, which counts as an SPF failure. Microsoft's own FAQ puts it plainly: "If you exceed 10 DNS lookups, your SPF check might fail."

A failed SPF check is not always fatal: DMARC passes if DKIM passes and aligns. But Gmail and Yahoo require bulk senders to have both SPF and DKIM working, and Microsoft requires both to pass for senders of more than 5,000 messages a day to Outlook.com. A broken SPF record also stops protecting you, since nothing after the limit is ever checked.

Count yours

The checker resolves every include the way a receiver does, numbers each lookup, and names the one that breaks the limit. Open "SPF record" under "Records found" to see the tree.

Check your domain's email setup

Runs in your browser. Lookups go straight from your browser to Cloudflare's public DNS resolver (Google Public DNS if Cloudflare fails). MailSetupCheck has no server and never sees the domain you check.

The part after the @ in your email address. You can paste a website address or an email address too.

Options: DKIM selector and DMARC report address

Where to find your selector: open a message you sent, view the original or raw message, and read s= in the DKIM-Signature line. The checker also tries 34 common selectors.

Used only to fill in the DMARC record the checker suggests. It is not looked up or sent anywhere.

What common services cost

Each row is what adding that service's include to your record costs: 1 for the include itself, plus its own lookups. Measured with this site's checker from live DNS on 8 October 2026. Vendors change these records without notice, which is why Google's and Microsoft's now cost a single lookup each.

Service Include Lookups it costs you
Freshdesk include:email.freshdesk.com 7
iCloud+ custom domains include:icloud.com 5
Mailgun include:mailgun.org 5
Zoho Mail include:zohomail.com 2
Proton Mail include:_spf.protonmail.ch 2
SendGrid include:sendgrid.net 2
Salesforce include:_spf.salesforce.com 2
Google Workspace include:_spf.google.com 1
Microsoft 365 include:spf.protection.outlook.com 1
Fastmail include:spf.messagingengine.com 1
Amazon SES (custom MAIL FROM) include:amazonses.com 1
Mailjet include:spf.mailjet.com 1
Postmark include:spf.mtasv.net 1
Mailchimp (older setups) include:servers.mcsv.net 1
Mailchimp Transactional (Mandrill) include:spf.mandrillapp.com 1
Zendesk include:mail.zendesk.com 1
Help Scout include:helpscoutemail.com 1
Shopify include:shops.shopify.com 1
Campaign Monitor include:_spf.createsend.com 1
Marketo include:mktomail.com 1

Raw data: spf-include-costs.json. Method: Each include was resolved with MailSetupCheck's SPF expander (engine/tools/email-auth-check/core.js) over Cloudflare DNS-over-HTTPS, counting include, a, mx, ptr, exists and redirect terms the way RFC 7208 section 4.6.4 does. cost_in_your_record = 1 (the include itself) + nested_lookups. Vendors change these records without notice; re-run data/mail/measure_spf_includes.mjs.

A few rows deserve a second look. include:shops.shopify.com resolves to v=spf1 ~all, which authorizes no servers at all. Salesforce's include uses an exists: term with a macro, which is resolved per message. Freshdesk's include alone costs 7.

How to fix it, safest first

1. Delete includes for services you no longer use

Old newsletter tools, a help desk you left, a CRM trial. Each one costs lookups, and if the vendor has removed its record, it also counts as a void lookup. Ask whoever manages your domain what every include is for. If nobody knows, look for the vendor in your billing records before you delete it.

2. Delete includes that do nothing for you

SPF checks the domain in the message's bounce address (the Return-Path), not the From address you see. Many sending services use their own bounce domain, so receivers check SPF against the service's domain, not yours. For mail like that, the service's include in your record costs lookups and adds nothing. DMARC then passes through DKIM, as long as the service signs with your domain.

To check: send a message through the service to a Gmail address, choose "Show original", and read the Return-Path. If it is not your domain or a subdomain of it, the include is not doing anything for that service's mail. Make sure the same message shows dkim=pass with your domain and dmarc=pass before you remove the include.

3. Replace a and mx with the addresses they stand for

a and mx each cost a lookup, and mx also has to look up every mail server's address. If they refer to servers you run with fixed addresses, list those addresses with ip4: and ip6:, which are free. Do not do this for a hosted provider's servers; their addresses change.

4. Move a sending service to a subdomain

Send newsletters as news.example.com and invoices as billing.example.com. Each subdomain gets its own SPF record with its own 10-lookup budget, and its own DKIM. With DMARC's default relaxed alignment, mail from news.example.com still aligns with your organization's domain. This is the cleanest fix when you genuinely need many services.

5. Flatten only with automation

"Flattening" replaces includes with the IP ranges they currently contain. It works until a vendor adds a server, and then that vendor's mail quietly starts failing. Microsoft asks customers not to flatten its include. If you flatten, use a service or script that re-reads the vendor records every day and updates yours.

Other SPF mistakes the checker catches

Sources: RFC 7208, Google's SPF setup guide, Microsoft's SPF guide.

Also available as Markdown.