Why the failure appears only after the new provider is added

SPF is evaluated as a program, not as a character count. A record can contain only two visible include mechanisms and still cause many DNS queries because each included policy can reference additional include, a, mx, exists, or redirect terms. RFC 7208 limits the number of terms that cause DNS queries during one SPF evaluation. Once the evaluation exceeds that ceiling, the receiver returns PermError instead of continuing until it finds a pass. That distinction matters operationally: the new provider may be configured correctly, yet its addition exposes that the whole authorization tree no longer fits inside the protocol budget. Treat the timing of the incident as a clue, not as a verdict against the provider you just added.

Reproduce the receiver’s path instead of counting visible includes

Start with the exact SPF identity shown in the failed message, usually the MAIL FROM or Return-Path domain. Query that hostname and then follow every branch that can be reached for the sending IP. Do not count only the first-level include statements. An include can trigger another policy that contains several more DNS-querying terms, while ip4 and ip6 mechanisms do not consume the same lookup budget. Write the expansion as a tree and mark which branches were actually evaluated. This produces a useful artifact for future migrations: when another service is added, you can see how much headroom remains instead of discovering the limit in production.

dig TXT example.com +short
dig TXT _spf.provider.example +short

Separate a PermError from an ordinary SPF fail

A normal SPF fail means the policy was evaluated successfully and the sending IP did not satisfy it. PermError means the receiver could not correctly evaluate the published policy, for example because of excessive DNS-querying terms, multiple SPF records, or invalid syntax. The repair path is therefore different. Adding another include to a PermError usually makes the policy more complex and can make the problem worse. First establish which exact error you have in Authentication-Results or the SMTP diagnostic. Then fix the record structure and retest from a message that actually uses the affected Return-Path domain.

Remove dead authorization before adding clever workarounds

The safest first reduction is administrative rather than technical: remove senders you no longer use. Old newsletter services, abandoned transactional platforms, and legacy gateways often remain in SPF years after the account was closed. Each stale include can consume lookup budget and can also create void-query problems if the referenced name stops returning useful data. Verify ownership before deleting anything, but prefer simplifying the source list over introducing a complicated flattening system. A short policy that matches the services you truly operate is easier to audit during an incident and less likely to drift out of sync with vendor infrastructure.

Use subdomains when mail streams have genuinely different infrastructure

A dedicated sending subdomain can have its own SPF policy because it is a separate DNS name. That can be useful when corporate mail and outbound campaign mail use different envelope domains and different providers. It is not a magic reputation reset and it does not excuse broken DMARC alignment; it is simply an architectural way to keep unrelated authorization trees from competing for the same SPF lookup budget. Before changing envelope domains, verify how the outbound provider constructs Return-Path and whether that domain will still align with the visible From domain under your DMARC settings.

Be cautious with flattening

SPF flattening replaces dynamic include chains with explicit IP addresses. That can reduce DNS lookups, but it transfers responsibility for provider IP changes to whoever maintains the flattened record. If a provider rotates or expands its sending ranges and your record is stale, legitimate mail can suddenly fail SPF. For a solo operator, the operational cost can outweigh the elegance of the shorter lookup tree. If flattening is used at all, document who refreshes it, how often, what source is authoritative, and how you will detect drift. Do not copy a one-time flattened value into DNS and assume it will remain correct indefinitely.

A worked migration check

Imagine the old policy authorizes Workspace and one billing service. A new outbound platform is added with another include. The visible record now has three includes, but the Workspace branch expands into several queries and the billing branch expands into two more. The new outbound branch then pushes the evaluation beyond the allowed total. The correct rollback is not necessarily to remove outbound permanently. First remove any obsolete sender, move an unrelated stream to its own envelope subdomain if the architecture supports it, and retest. The key decision is whether the resulting policy remains understandable and maintainable by the person who will be on call the next time deliverability changes.

Retest the message, not just the DNS checker

After changing SPF, query DNS from more than one resolver and then send a new message through each active provider. Inspect Authentication-Results for SPF and DMARC, and confirm the Return-Path is the one you expected. A web checker can tell you that a record parses, but it cannot prove that your real outbound message chose the expected envelope domain or that a provider did not switch infrastructure. Keep the before-and-after headers with the change log. If the PermError disappears but DMARC still fails, the next investigation is alignment rather than SPF lookup count.

Turn the lookup budget into a pre-change gate

For a small outbound operation, the useful control is a pre-change SPF budget, not a post-incident checker screenshot. RFC 7208 limits the SPF evaluation to ten terms that cause DNS queries. Before adding a provider, expand the current record and record the worst evaluation path for the identities that actually send. Then model the proposed include before publishing it. If the tree is already close to the limit, the migration plan should change before DNS does: retire an old sender, use a separate envelope subdomain for a genuinely separate stream, or choose an integration that does not add another deep include chain. This is especially important when a provider’s top-level record looks harmless but delegates through several names underneath it.

Keep the budget sheet beside the provider inventory. One row should name the envelope domain, one should name each include owner, and another should record why that sender still exists. Re-run the expansion after provider-side changes because an include can become deeper without your visible SPF TXT record changing at all. The objective is not to sit permanently at nine lookups; it is to know whether a future vendor change can push a previously healthy path into PermError. That turns a fragile DNS string into an auditable dependency map and gives a solo operator a clear rollback point when authentication changes unexpectedly.

Field checklist

  • Identify the exact MAIL FROM or Return-Path domain from a failed message.
  • Expand nested include branches; do not count only the visible record.
  • Remove obsolete senders before considering flattening.
  • Keep separate SPF policies only on genuinely separate domain names or subdomains.
  • Retest every active sending path after the DNS change.
  • Confirm DMARC alignment after SPF returns to pass.

Primary sources

Standards and provider policies can change. These links are the reference points used for this field note.

  1. RFC 7208 — Sender Policy FrameworkIETF / RFC EditorSPF protocol and evaluation semantics.
  2. Gmail SMTP errors and codesGoogle Gmail HelpTemporary and permanent Gmail SMTP errors, including authentication and unusual-rate failures.
  3. RFC 9989 — DMARCIETF / RFC EditorCurrent DMARC base specification, published May 2026.