Email authentication · SPF

Too many DNS lookups in SPF: why mail fails and how to fix it

The short answer

SPF lets a receiver make at most 10 DNS lookups while it checks your record (RFC 7208, section 4.6.4). Every include, a, mx, ptr and exists term counts, and so does redirect, including the ones inside your vendors' records. At 11 the check stops with a PermError, SPF fails for every message, and DMARC then rests on DKIM alone.

The math, on one record

A fictional company, example.com, sends mail through Microsoft 365 and a Freshdesk help desk. Years ago someone also added SendGrid. The record has five terms and looks harmless:

v=spf1 mx include:spf.protection.outlook.com include:email.freshdesk.com include:sendgrid.net -all
TermWhat the receiver has to look upLookups
mxThe domain's mail hosts.1
include:spf.protection.outlook.comMicrosoft 365. Its record lists addresses only.1
include:email.freshdesk.comFreshdesk. Its record includes SendGrid (2) and four regional Freshdesk records (1 each).7
include:sendgrid.netSendGrid. Its record includes one more record of its own.2
-allFail everything else. No lookup.0
Total, against a limit of 1011: PermError

Two changes bring it to 8. SendGrid's addresses already come in through Freshdesk's record, so the separate include costs 2 lookups and adds no address. If mail only leaves through Microsoft 365, the mx term adds nothing either. 11 − 2 − 1 = 8, with room for one more vendor.

Vendor costs measured on 11 November 2026 against public DNS. Vendors change their own records without notice, which is why the checker reads them live instead of from a list.

What breaks, and who notices

  • The receiver stops at the eleventh lookup. The result is PermError, a permanent error. It does not read the rest of your record, so even your Microsoft 365 servers are no longer recognised. RFC 7208 §4.6.4
  • Most receivers treat PermError like a failure. What they do with it is their choice: spam folder, refusal, or a lower reputation score. None of them tell you. RFC 7208 §8.7
  • DMARC loses its SPF half. DMARC passes when SPF or DKIM passes and matches your From domain. With SPF broken, every message that is not DKIM-signed for your domain fails DMARC, and under p=quarantine or p=reject it is filtered or refused. RFC 7489 §3.1
  • It can break while you change nothing. The lookups inside a vendor's record are the vendor's to change. A record at 9 today reaches 11 the day a vendor adds a region.
  • You hear about it last. No receiver emails you a PermError. Your DMARC aggregate reports show it a day later, if someone reads them.

Count your own record

The free SPF checker draws your include tree with the cost of every branch, so you see which vendor uses up your lookups.

Free, no account. We read only public DNS and what your servers show to anyone who connects.

Fix it, step by step

  1. List what really sends mail as your domain

    Read your DMARC aggregate reports, or ask each team: help desk, CRM, invoicing, newsletters. An include for a service nobody uses any more is a lookup you get back for free.

  2. Count every branch, not only your own terms

    Run the SPF checker. It follows every include down to the last record and shows what each one costs. Start with the costliest branch.

  3. Remove duplicates and dead entries

    Drop includes for services you left, includes that another vendor's record already contains, and mx or a terms for hosts that never send mail. Remove ptr in any case: RFC 7208 says it SHOULD NOT be used (§5.5).

  4. Move bulk mail to a subdomain

    Send newsletters with a return-path on a subdomain such as news.example.com, with its own SPF record. That name has its own budget of 10 lookups, and under DMARC's default relaxed alignment it still matches mail from example.com.

  5. List your own fixed servers by address

    A server you run, with a fixed address, can be listed as ip4: or ip6:. Those terms cost nothing. Do not copy a vendor's addresses this way: vendors change them without telling you.

  6. Check again, then keep watching

    Check once more after the DNS change has spread. Then let SkyQon watch the domain: it alerts you at 9 or 10 lookups, before a vendor's change pushes you over.

Common mistakes

Counting only the includes you can see

Five terms look safe. The limit applies to the whole tree, and Freshdesk's one include costs 7 on its own today.

In SkyQon's result: each include shows its own subtotal, and the costliest branch is marked.

Thinking a repeated include is free

If two vendors include the same record, the receiver looks it up twice and both count. RFC 7208 has no de-duplication.

In SkyQon's result: a repeated include appears in every branch that uses it, each time with its cost.

Copying vendor addresses into your record

It lowers the count today. When the vendor adds a server, your copy does not know, and their mail fails your SPF with no error anywhere. A hosted SPF service that rewrites your record has the same weakness in reverse: its include sits in your record, and if that service stops, so does your mail authentication.

In SkyQon's result: ip4 and ip6 terms cost 0 in the tree. The checker cannot tell whether a copied range still belongs to the vendor, which is why we advise against copying.

Adding a second SPF record for a new vendor

Two TXT records that start with v=spf1 is a PermError on its own, whatever the count (RFC 7208 §3.2). Add the new include to the one record you have.

In SkyQon's result: a multiple-records finding, with both records shown.

What SkyQon does and does not do

What it finds

Your SPF record and every record it includes, with the lookups each branch costs. Also: more than one SPF record, a template placeholder such as <ip> left in the record, more than two void lookups, and an all that lets everyone send.

What you get

The count against the limit of 10, the branch to cut first, your record in a box you can copy, and on a monitored domain an alert at 9 or 10 lookups and another past 10.

What it is not

We do not host or rewrite your SPF record. Your SPF stays yours: no SkyQon include inside it, and nothing that stops working if you leave us.

SPF lookups: questions people ask

Which SPF terms count towards the 10-lookup limit?
include, a, mx, ptr and exists, plus the redirect modifier. ip4, ip6, all and exp cost nothing. The qualifier and a CIDR suffix change nothing: ~include, +a and a/24 each cost 1.
Do the lookups inside an include count?
Yes. The receiver follows every include down, and every lookup term in every record it reaches counts against the same budget of 10. That is how one include can cost 7.
Is the limit per record or per message?
Per SPF check: one evaluation of your record for one message, with everything it pulls in. A subdomain with its own record starts again at 0.
What is a void lookup?
A lookup that returns no answer, or an answer saying the name does not exist. RFC 7208 says receivers should allow at most two per check; more is a PermError. An include that points at a vendor record that was deleted is the usual cause.
Does the mx term cost more than one lookup?
It costs 1 against the limit of 10. The address lookups for the mail hosts it returns do not count towards 10, but there may be no more than 10 of them, or the mx term itself returns PermError.
Does a subdomain inherit my SPF record?
No. SPF is checked against the exact domain in the envelope sender, or the server's HELO name. A subdomain that sends mail needs its own record. One that never sends mail should publish v=spf1 -all so nobody else can use it.
Why does SkyQon not flatten my SPF record?
Flattening replaces includes with the vendor's current addresses. The count drops until the vendor changes an address, and then mail fails without warning. Hosted or dynamic SPF avoids that by putting the hosting company's include in your record, so your mail authentication depends on that company. We count, explain and alert instead, and the record stays yours.
How often does SkyQon recount?
On a monitored domain, every scan recounts the whole tree. The free plan watches up to 5 domains and alerts you at 9 or 10 lookups and again past 10. The checker on this page is a one-off count you can run any time.
My count differs from another tool. Which is right?
Tools differ in two places: whether a repeated include is counted each time (RFC 7208 counts each evaluation, and so do we), and what happens when a branch cannot be read. If a DNS server does not answer, we mark the count incomplete instead of guessing.
Does fixing SPF fix DMARC?
Only the SPF half. DMARC passes when SPF or DKIM passes and matches your From domain. DKIM signing with your own domain keeps mail passing DMARC even on a day SPF fails, so set up both.

Hear about it at 9, not after 11.

Add your domain to the free plan. SkyQon recounts your SPF tree on every scan and alerts you before a vendor's change pushes you over the limit.