Como corrigir 'SPF PermError: Too Many DNS Lookups', na prática
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 retornapermerror. - 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 termomxconta como uma consulta, e os hosts MX que ele retorna não podem resolver para mais de 10 endereços. Optraparece 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:
- 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. - O registro raiz tira o
include:mailgun.orge 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