Todos os artigos

Como corrigir 'SPF PermError: Too Many DNS Lookups', na prática

··8 min de leitura

O SPF permite no máximo 10 termos que fazem consultas DNS por avaliação. Cada include, a, mx, ptr, exists e redirect conta, inclusive os aninhados dentro dos registros incluídos. Passou de 10, os receptores retornam permerror, que o DMARC trata como falha. A correção é remover os includes de que você não precisa, mover remetentes para subdomínios ou trocar nomes de host por faixas de IP.

A regra está na RFC 7208, seção 4.6.4: "As implementações de SPF DEVEM limitar o número total desses termos a 10 durante a avaliação do SPF... Se esse limite for excedido, a implementação DEVE retornar 'permerror'." (As citações neste texto são traduções livres dos originais em inglês.) A maioria dos guias para por aí. O útil é saber quanto cada include custa de fato, então medimos.

Quanto custam os includes comuns

Contamos as consultas por trás do include de SPF publicado por cada provedor em 1º de outubro de 2026, usando dig e um pequeno script que percorre a árvore de includes. O custo é o próprio include mais cada termo que gera consulta abaixo dele. Isso muda sempre que um provedor edita os registros, então confira de novo antes de confiar em um número.

Include Consultas que custa Por quê
_spf.google.com (Google Workspace) 1 Lista simples de faixas de IP
spf.protection.outlook.com (Microsoft 365) 1 Simples
servers.mcsv.net (Mailchimp) 1 Simples
amazonses.com (Amazon SES) 1 Simples
mail.zendesk.com 1 Simples
spf.mandrillapp.com 1 Simples
spf.brevo.com 1 Simples
spf.mtasv.net (Postmark) 1 Simples
mktomail.com (Marketo) 1 Simples
sendgrid.net 2 Aninha ab.sendgrid.net
_spf.salesforce.com 2 Usa uma macro exists:
sparkpostmail.com 2 Um include aninhado
zohomail.com 2 Um include aninhado
mailgun.org 5 Quatro includes aninhados
zoho.com 5 Quatro includes aninhados

A maioria dos includes de um único provedor custa uma consulta. Os caros são os provedores que aninham vários níveis. Dois desses no mesmo registro gastam 10 do seu orçamento juntos.

Um registro real acima do limite

Contar o registro SPF de gitlab.com em 1º de outubro de 2026 dá 13. Escolhemos esse porque é um registro público de uma empresa bem administrada que mostra exatamente como os registros vão passando do limite: um fornecedor de cada vez. Este é o registro de nível superior, com a contagem acumulada na ordem de avaliação:

v=spf1 include:mail.zendesk.com      # 1
       include:_spf.google.com       # 2
       include:mktomail.com          # 3
       include:_spf.salesforce.com   # 4, plus exists: inside = 5
       include:_spf-ip.gitlab.com    # 6
       a:zgateway.zuora.com          # 7
       include:mailgun.org           # 8
         -> include:_spf.mailgun.org       # 9
              -> include:_spf1.mailgun.org # 10
              -> include:_spf2.mailgun.org # 11
         -> include:_spf.eu.mailgun.org    # 12
       include:_spf.sendergen.com    # 13
       ip4:35.80.141.6/32 ip4:44.229.121.55/32 -all

Nada aqui é incomum. Cada linha é um fornecedor legítimo, e o excesso vem quase todo de mailgun.org, que sozinho custa cinco.

Por que não falha o tempo todo

O limite é aplicado durante a avaliação, e o SPF avalia da esquerda para a direita, parando na primeira correspondência. Seguindo a RFC à risca:

  • O e-mail enviado das faixas de IP do Google corresponde na consulta 2 e passa. O limite nunca é atingido.
  • O e-mail do primeiro bloco de faixas do Mailgun (_spf1) corresponde na consulta 10 e passa, por pouco.
  • O e-mail do segundo bloco do Mailgun (_spf2) precisa da consulta 11, então o receptor retorna permerror.
  • O e-mail do último include nem chega a ser avaliado.

Ou seja, o mesmo registro passa para alguns remetentes e falha para outros. É por isso que problemas de "too many lookups" (consultas demais) costumam aparecer como o e-mail de uma ferramenta falhando no DMARC enquanto todo o resto parece normal. Um verificador estático que conta a árvore inteira, como o script abaixo, informa 13 seja qual for o servidor que enviou a mensagem. De qualquer jeito, não dá para confiar em um registro acima de 10.

Conte o seu próprio registro

Rode isto em qualquer máquina com Python 3 e dig. Ele imprime a árvore e o total.

import subprocess, re, sys

def spf(name):
    out = subprocess.run(["dig", "+short", "TXT", name], capture_output=True, text=True).stdout
    recs = ["".join(re.findall(r'"((?:[^"\\]|\\.)*)"', l)) for l in out.splitlines()]
    return [r for r in recs if r.lower().startswith("v=spf1")]

def count(name, depth=0):
    recs = spf(name)
    print("  " * depth + name + ": " + (recs[0] if recs else "NO SPF RECORD"))
    if not recs:
        return 0
    total = 0
    for term in recs[0].split()[1:]:
        t = term.lstrip("+-~?").lower()
        if t.startswith("include:"):
            total += 1 + count(t.split(":", 1)[1], depth + 1)
        elif t.startswith("redirect="):
            total += 1 + count(t.split("=", 1)[1], depth + 1)
        elif t in ("a", "mx", "ptr") or t.startswith(("a:", "a/", "mx:", "mx/", "ptr:", "exists:")):
            total += 1
    return total

print("TOTAL:", count(sys.argv[1]))

python3 spf_count.py yourdomain.com. Ou use o nosso verificador de SPF, que faz a mesma contagem sem terminal.

Dois outros limites na mesma seção da RFC pegam muita gente de surpresa:

  • Consultas vazias. A RFC 7208 diz que as implementações "DEVERIAM limitar as 'consultas vazias' a duas", ou seja, consultas que não retornam registros ou que caem em um domínio inexistente. Um include que aponta para um fornecedor que você deixou de usar, cujo registro já foi apagado, gasta uma delas.
  • O mecanismo mx. Cada termo mx conta como uma consulta, e os hosts MX que ele retorna não podem resolver para mais de 10 endereços. O ptr aparece como "não use" na RFC.

E um que não é limite de consultas, mas gera o mesmo permerror: publicar dois registros SPF separados no mesmo domínio. Junte os dois em um só.

Como voltar para baixo de 10

Siga nesta ordem. Os dois primeiros passos resolvem a maioria dos registros sem nenhuma manutenção depois.

1. Remova os includes que não fazem nada por você

O SPF checa o domínio do remetente do envelope (o Return-Path, ou MAIL FROM), não o endereço From que seus destinatários veem. Muitas plataformas de e-mail colocam por padrão o próprio domínio de bounce no remetente do envelope. Se a sua faz isso, os receptores checam o SPF contra o domínio da plataforma e o include do seu registro nunca é consultado.

Para conferir, mande uma mensagem para você mesmo por cada plataforma e olhe o cabeçalho Return-Path:

Se o Return-Path mostra... Você precisa do include?
bounce@yourdomain.com ou um subdomínio seu Sim, o SPF é checado contra o seu domínio
bounces+123@em.platform.com ou algo parecido Não, remova. O alinhamento DMARC vem do DKIM

O segundo caso só funciona se a plataforma assinar o DKIM com o seu domínio, então confirme isso com o nosso verificador de DKIM antes de apagar qualquer coisa. Apague também os includes de ferramentas que você não usa mais. Includes antigos são a fonte mais comum de consultas vazias.

2. Mova remetentes para subdomínios

Cada subdomínio tem o próprio registro SPF e o próprio orçamento de 10. Coloque o marketing em news.seudominio.com e o suporte em help.seudominio.com, configure a plataforma para usar esse subdomínio como domínio de return-path personalizado, e o seu registro raiz só precisa cobrir as suas caixas de e-mail. O alinhamento DMARC continua funcionando, porque o alinhamento relaxado (o padrão) considera alinhados os subdomínios do mesmo domínio organizacional.

3. Troque consultas de nome de host por faixas de IP que você controla

Um a: ou mx que aponta para o seu próprio servidor custa uma consulta toda vez. Se o IP é fixo e seu, ip4:203.0.113.10 não custa nada.

4. Achate, com cuidado

O achatamento de SPF troca os includes pelos IPs para os quais eles resolvem no momento. Ele deixa você abaixo do limite com segurança e fica desatualizado com a mesma segurança, porque os provedores mudam as faixas sem avisar. Se for achatar, faça com um serviço ou um script agendado que resolva e publique de novo, e não achate provedores como o Salesforce, cujo registro usa uma macro exists:. Aquilo não é uma lista de IPs, então não há o que achatar.

Uma correção, do começo ao fim

Esta é uma empresa hipotética usando os custos medidos na tabela acima. As caixas de e-mail estão no Google Workspace, o marketing sai pelo SendGrid, as notificações do produto pelo Mailgun, e vendas e suporte usam Salesforce e Zendesk:

v=spf1 include:_spf.google.com include:sendgrid.net include:mailgun.org
       include:_spf.salesforce.com include:mail.zendesk.com ~all
Include Custo
_spf.google.com 1
sendgrid.net 2
mailgun.org 5
_spf.salesforce.com 2
mail.zendesk.com 1
Total 11

Um a mais. Duas mudanças resolvem sem achatar nada:

  1. As notificações do produto passam para notify.example.com, com o Mailgun configurado para usar esse subdomínio no remetente do envelope. O subdomínio ganha o próprio registro, v=spf1 include:mailgun.org ~all, que custa 5 das 10 dele.
  2. O registro raiz tira o include:mailgun.org e cai para 6.

Isso deixa quatro consultas de folga no domínio raiz para a próxima ferramenta que alguém assinar, e mantém os includes aninhados do Mailgun num lugar onde eles não empurram mais nada para cima do limite.

Depois da correção

Conte de novo e depois mande um teste por cada plataforma que você usa e confira Authentication-Results procurando spf=pass. Lembre que o SPF é uma de três checagens. O DMARC passa se o SPF ou o DKIM passar e estiver alinhado, então uma boa configuração de DKIM é o que impede que um problema temporário de SPF vire um problema de entrega. O nosso gerador de SPF monta um registro novo se você preferir começar do zero em vez de editar o antigo.

O registro que você tem hoje foi montado um fornecedor de cada vez. Conte de novo sempre que acrescentar um.

Perguntas frequentes

Quais mecanismos do SPF contam para o limite de 10 consultas DNS?

Pela RFC 7208, os mecanismos include, a, mx, ptr e exists e o modificador redirect contam cada um como uma consulta, e as consultas dentro dos registros incluídos também contam. Os mecanismos ip4, ip6 e all não contam, e é por isso que trocar nomes de host por faixas de IP reduz o total.

O que acontece quando um registro SPF passa de 10 consultas?

O servidor receptor deve retornar um resultado permerror em vez de pass ou fail. Como o limite é aplicado durante a avaliação, um e-mail que corresponde a um mecanismo do começo ainda pode passar, enquanto o de um remetente listado mais adiante falha, o que faz o problema parecer intermitente.

O achatamento de SPF (SPF flattening) é uma boa solução?

Funciona, mas é frágil. O achatamento troca os includes pelas faixas de IP para as quais eles resolvem no momento, então quando um provedor muda os IPs o seu registro fica desatualizado sem aviso. Use só com um serviço ou script que refaça o achatamento automaticamente, e antes tente remover os includes desnecessários.

Preciso de um include para cada plataforma de e-mail que uso?

Só para as plataformas que enviam com o seu domínio no remetente do envelope (Return-Path). Muitas plataformas colocam ali o próprio domínio de bounce; nesse caso o SPF é checado contra o domínio delas, não o seu, e o seu include não faz nada. Essas plataformas dependem do DKIM para o alinhamento DMARC.

Verifique e-mails por USD 39,00/mês, sem bloqueio

Checagem SMTP real da caixa postal. Sem créditos e sem cobrança por e-mail.

Começar agora

Leia o original em inglês