# How to fix SPF PermError: too many DNS lookups

URL: https://iblockspam.com/blog/spf-too-many-dns-lookups
Last updated: 2026-10-09
Published: 2026-10-09
Topic: SPF, DKIM & DMARC
Author: iBlockSpam Team

> Why SPF breaks at 10 DNS lookups, how to count them, and step-by-step fixes for Microsoft 365 and Google Workspace domains with many senders.

## Short answer

SPF allows at most 10 DNS-querying terms (include, a, mx, ptr, exists and redirect) per check. Over that, receivers return PermError and your SPF stops counting. To fix it, remove unused senders, drop a and mx where they don't send, move bulk tools to subdomains, and rely on aligned DKIM for DMARC.

## What does "too many DNS lookups" mean in SPF?

SPF ([RFC 7208](https://www.rfc-editor.org/rfc/rfc7208.html)) is a TXT record listing who may send mail for your domain. To check it, a receiving server may need to make more DNS queries: one for each `include`, each `a`, each `mx`, and so on, including inside the records you include.

To stop SPF being used to flood DNS servers, section 4.6.4 of the RFC sets hard limits:

| Limit | What counts | What happens if exceeded |
|---|---|---|
| 10 DNS-querying terms per evaluation | `include`, `a`, `mx`, `ptr`, `exists`, `redirect` | PermError |
| 2 void lookups (recommended) | Lookups that return no records or "domain doesn't exist" | PermError |
| 10 address lookups per `mx` mechanism | The A/AAAA lookups for each MX host | That `mx` returns PermError |
| 10 address lookups per `ptr` | Names returned by the reverse lookup | Extra names are ignored |
| Free | `ip4`, `ip6`, `all` | — |

The 10 is counted across the **whole tree**. If you include a vendor whose record includes three more records, that's four lookups, not one.

When a receiver gets PermError, your SPF result is unusable. For DMARC ([RFC 9989](https://www.rfc-editor.org/rfc/rfc9989.html)), that means SPF can't provide the aligned pass. If DKIM doesn't pass and align either, DMARC fails.

## Why do Microsoft 365 and Google Workspace domains hit the limit?

Neither platform's base record is the problem on its own. When we looked up both records on 9 October 2026, `spf.protection.outlook.com` and `_spf.google.com` each contained only `ip4` and `ip6` ranges, so each include cost one lookup.

The trouble is everything added over the years:

- A newsletter platform, a CRM, a helpdesk, an invoicing tool, a website contact form.
- `a` and `mx` mechanisms added "just in case", which cost a lookup each.
- Includes for services you stopped using, which often become void lookups.
- A filtering service's include added to SPF even though it only handles **inbound** mail.

Each vendor tells you to add their include. Nobody adds up the total. Our [SPF records by email provider](https://iblockspam.com/spf) table lists what each common include costs, measured, and which services don't need one at all.

## How do you count SPF lookups by hand?

A checker does this for you, but knowing the method helps you judge each vendor's request before you add it.

1. Start at your domain's SPF record. Every `include`, `a`, `mx`, `ptr`, `exists` and `redirect` costs one.
2. For each `include`, fetch that domain's SPF record and repeat. Its mechanisms count toward **your** total too.
3. Ignore `ip4`, `ip6` and `all`. They cost nothing.
4. Note any lookup that returns no record or a non-existent domain. That's a void lookup; more than two is PermError.
5. Stop at 11. If you reach it, the record is broken for every receiver that follows the RFC.

For example, `v=spf1 mx include:spf.protection.outlook.com include:vendor.example -all`, where `vendor.example` itself contains two more includes, costs 1 (`mx`) + 1 (Microsoft) + 1 (vendor) + 2 (vendor's includes) = 5.

Our [SPF records by email provider](https://iblockspam.com/spf) pages list the measured cost of each common include, from [Microsoft 365](https://iblockspam.com/spf/microsoft-365) and [Google Workspace](https://iblockspam.com/spf/google-workspace) to sending services such as [SendGrid](https://iblockspam.com/spf/sendgrid) and [Amazon SES](https://iblockspam.com/spf/amazon-ses).

## Does switching to ~all or +all fix it?

People sometimes try to make the error go away by loosening the ending. It doesn't work. The lookup limit is reached before the `all` mechanism is ever evaluated, so changing `-all` to `~all` changes nothing. Changing it to `+all` makes SPF meaningless, because it authorizes every server on the internet to send as you. Removing SPF entirely is worse still: Google and Yahoo require SPF from bulk senders, and receivers lose a signal that helps your real mail.

## How do you fix too many SPF lookups?

1. **Measure where you are.** Run your domain through the [SPF Checker](https://iblockspam.com/tools/spf-checker). Note the total lookup count, the void lookup count, and which branch of the include tree uses the most.

2. **Check for duplicate records.** If there are two TXT records starting with `v=spf1`, that alone is PermError (RFC 7208, section 4.5). Merge them into one before doing anything else.

3. **List who really sends as your domain.** Check DMARC aggregate reports if you have them. Otherwise ask each team what tools send email "from" your domain. Write down each service and whether it sends from the main domain or could use a subdomain.

4. **Remove what you don't use.** Delete includes for retired services. This often fixes void lookups at the same time.

5. **Drop `a`, `mx` and `ptr` unless they send.** `mx` authorizes your inbound servers to send. If your MX points to Microsoft 365, Google, or a filtering service, `mx` is usually redundant because the platform include already covers outbound. `ptr` is slow and RFC 7208 says not to use it.

6. **Don't add inbound-only services.** A filtering service that only receives mail for you doesn't need to be in your SPF. Only add an include for a service that sends mail with your domain in the envelope sender, such as an outbound relay.

7. **Move bulk and marketing senders to a subdomain.** For example, send newsletters from `news.example.com`. That subdomain gets its own SPF record with its own budget of 10:

   ```
   example.com.       TXT  "v=spf1 include:spf.protection.outlook.com -all"
   news.example.com.  TXT  "v=spf1 include:mailer.example.net -all"
   ```

   With relaxed alignment (the DMARC default), `news.example.com` still aligns with `example.com`.

8. **Set up DKIM everywhere.** Configure custom DKIM signing with your domain in each sending tool. DMARC passes if **either** SPF or DKIM passes with alignment, so DKIM gives you a second route and survives forwarding better.

9. **Consider flattening only as a last resort.** Replacing an include with the vendor's current `ip4`/`ip6` ranges saves lookups, but breaks the moment the vendor changes addresses. If you flatten, automate updates.

10. **Re-check and monitor.** Run the checker again. Vendors change their own records, so a record that passes today can break next month without you touching it.

## Example: before and after

A Microsoft 365 domain that had grown over time:

```
Before:
v=spf1 a mx include:spf.protection.outlook.com include:_spf.google.com
  include:mailer.example.net include:crm.example.org include:helpdesk.example.io
  include:old-newsletter.example.com include:invoices.example.co ~all
```

The domain moved from Google Workspace to Microsoft 365 two years ago, and the old newsletter service is gone. After removing those, dropping `a mx`, and moving the newsletter tool to a subdomain:

```
After:
example.com.       TXT "v=spf1 include:spf.protection.outlook.com include:crm.example.org
                        include:helpdesk.example.io include:invoices.example.co -all"
news.example.com.  TXT "v=spf1 include:mailer.example.net -all"
```

The exact count depends on what each vendor's include contains today. Measure, don't guess.

## What are the common mistakes?

| Mistake | Why it hurts | Fix |
|---|---|---|
| Two SPF records | PermError immediately | Merge into one |
| `redirect` plus `all` | `redirect` is ignored when `all` is present (section 6.1) | Use one or the other |
| `redirect` to a domain with no SPF | PermError, not "none" | Point it at a domain that publishes SPF |
| Using `+all` to "fix" failures | Authorizes the whole internet | Use `~all` or `-all` |
| Adding the inbound filter's include | Wastes a lookup on a host that doesn't send for you | Only list outbound senders |

## How do you check the fix worked?

DNS changes aren't instant. Resolvers keep the old record until its TTL expires, so wait at least that long before testing.

1. Run the [SPF Checker](https://iblockspam.com/tools/spf-checker) again and confirm the lookup count is 10 or under, with no more than two void lookups.
2. Send a test message from each service you kept, for example your mailbox, your CRM and your helpdesk, to a mailbox at a different provider.
3. Open each message's headers in the [Email Header Analyzer](https://iblockspam.com/tools/email-header-analyzer) and confirm `spf=pass` or, where SPF doesn't align, `dkim=pass` with alignment.
4. If you publish DMARC with a `rua` address, watch the next week of aggregate reports for any source that stopped passing.

Leave some headroom. A record sitting at exactly 10 breaks the moment one vendor adds an include to its own record.

## How iBlockSpam helps

Our free [SPF Checker](https://iblockspam.com/tools/spf-checker) counts lookups across the whole include tree and shows where they're spent, and the [SPF Record Generator](https://iblockspam.com/tools/spf-generator) estimates the lookup count of a rebuilt record before you publish it. If you use iBlockSpam for inbound filtering, you don't add anything to SPF for inbound mail. If you use our outbound relay (with DKIM signing, 500 messages per month included), the setup wizard shows what, if anything, to change in SPF and compares your DNS before and after. Domain monitoring alerts you when your SPF record changes: weekly on Protect, daily on Protect Plus. We don't flatten records for you.

## Next steps

1. Count your lookups with the free [SPF Checker](https://iblockspam.com/tools/spf-checker).
2. Remove includes for services you no longer use, then rebuild the record with the [SPF Record Generator](https://iblockspam.com/tools/spf-generator).
3. Re-check after every new sending service you add.

A record that is under the limit today can go over it when a vendor changes its include. The free [Free Domain Watch](https://iblockspam.com/free-monitoring) re-checks your SPF record every week and emails you if it changes.

Browse our other [SPF, DKIM and DMARC guides](https://iblockspam.com/blog/topic/authentication).

## Frequently asked questions

### Do ip4 and ip6 count toward the 10 lookup limit?

No. Only include, a, mx, ptr, exists and the redirect modifier count. ip4, ip6 and all don't need DNS queries, so you can list as many addresses as you like, within the size limits of a TXT record.

### Is SPF flattening a good idea?

It works, but it's fragile. Flattening copies a vendor's IP addresses into your record. When the vendor changes its addresses, your record is silently wrong. Only flatten with a tool that updates automatically, and prefer subdomains first.

### How many lookups does Microsoft 365 or Google Workspace use?

When we checked in October 2026, include:spf.protection.outlook.com and include:_spf.google.com each cost one lookup, because those records contain only IP ranges. Vendors can change that at any time, so check with our SPF Checker.

### Will a PermError make my mail bounce?

Usually not directly. SPF simply stops helping you. If DKIM passes and aligns, DMARC can still pass. If it doesn't, receivers may treat the message as unauthenticated and junk or reject it.

## Sources

- [RFC 7208: Sender Policy Framework (SPF), section 4.6.4 DNS Lookup Limits](https://www.rfc-editor.org/rfc/rfc7208.html#section-4.6.4)
- [RFC 7208, section 6.1: redirect modifier](https://www.rfc-editor.org/rfc/rfc7208.html#section-6.1)
- [Microsoft Learn: Set up SPF to identify valid email sources for your Microsoft 365 domain](https://learn.microsoft.com/en-us/defender-office-365/email-authentication-spf-configure)
- [Google Workspace Admin Help: Set up SPF](https://knowledge.workspace.google.com/admin/security/set-up-spf)
- [Gmail Help: Email sender guidelines](https://support.google.com/mail/answer/81126)
- [RFC 9989: DMARC](https://www.rfc-editor.org/rfc/rfc9989.html)

## Free tools for this guide

- [SPF Checker](https://iblockspam.com/tools/spf-checker): Count real DNS lookups, find PermErrors, loops and risky "all" settings.
- [SPF Record Generator](https://iblockspam.com/tools/spf-generator): Build a valid SPF record from your mail providers, with a DNS lookup count.
- [DMARC Checker](https://iblockspam.com/tools/dmarc-checker): Check your policy, reporting and the safe path from p=none to reject.
- [Email Health Check](https://iblockspam.com/tools/email-health-check): Grade your domain's MX, SPF, DKIM, DMARC and transport security in one scan.

---

Source: iBlockSpam, https://iblockspam.com/blog/spf-too-many-dns-lookups (this is a Markdown copy; the HTML page is canonical). Quote with attribution and a link. Site index for AI assistants: https://iblockspam.com/llms.txt
