Todos los artículos

Cómo arreglar 'SPF PermError: Too Many DNS Lookups', paso a paso

··8 min de lectura

SPF permite como máximo 10 términos que hacen consultas DNS por evaluación. Cada include, a, mx, ptr, exists y redirect cuenta, incluidos los que están anidados dentro de los registros incluidos. Si pasas de 10, los receptores devuelven permerror, que DMARC trata como un fallo. Se arregla quitando los include que no necesitas, moviendo remitentes a subdominios o reemplazando nombres de host por rangos de IP.

La regla está en el RFC 7208, sección 4.6.4: "SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation... If this limit is exceeded, the implementation MUST return 'permerror'." (Las implementaciones de SPF DEBEN limitar el número total de esos términos a 10 durante la evaluación de SPF... Si se supera este límite, la implementación DEBE devolver "permerror"). La mayoría de las guías se quedan ahí. Lo útil es saber cuánto cuesta en realidad cada include, así que lo medimos.

Cuánto cuestan los include comunes

Contamos las consultas detrás del include de SPF que publica cada proveedor el 1 de octubre de 2026, con dig y un pequeño script que recorre el árbol de include. El costo es el propio include más cada término que genera consultas por debajo de él. Esto cambia cada vez que un proveedor edita sus registros, así que vuelve a comprobarlo antes de fiarte de un número.

Include Consultas que cuesta Por qué
_spf.google.com (Google Workspace) 1 Lista plana de rangos de IP
spf.protection.outlook.com (Microsoft 365) 1 Plano
servers.mcsv.net (Mailchimp) 1 Plano
amazonses.com (Amazon SES) 1 Plano
mail.zendesk.com 1 Plano
spf.mandrillapp.com 1 Plano
spf.brevo.com 1 Plano
spf.mtasv.net (Postmark) 1 Plano
mktomail.com (Marketo) 1 Plano
sendgrid.net 2 Anida ab.sendgrid.net
_spf.salesforce.com 2 Usa una macro exists:
sparkpostmail.com 2 Un include anidado
zohomail.com 2 Un include anidado
mailgun.org 5 Cuatro include anidados
zoho.com 5 Cuatro include anidados

La mayoría de los include de un solo proveedor cuestan una consulta. Los caros son los proveedores que anidan varios niveles. Dos de esos en un mismo registro se comen 10 de tu presupuesto entre los dos.

Un registro real por encima del límite

Contar el registro SPF de gitlab.com el 1 de octubre de 2026 da 13. Lo elegimos porque es un registro público de una empresa bien gestionada que muestra exactamente cómo los registros se van pasando del límite: un proveedor a la vez. Este es el registro de nivel superior, con el conteo acumulado en orden de evaluación:

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 de esto es raro. Cada línea es un proveedor legítimo, y el exceso viene casi todo de mailgun.org, que por sí solo cuesta cinco.

Por qué no falla siempre

El límite se aplica durante la evaluación, y SPF evalúa de izquierda a derecha y se detiene en la primera coincidencia. Siguiendo el RFC al pie de la letra:

  • El correo enviado desde los rangos de IP de Google coincide en la consulta 2 y pasa. Nunca se llega al límite.
  • El correo del primer bloque de rangos de Mailgun (_spf1) coincide en la consulta 10 y pasa, por poco.
  • El correo del segundo bloque de Mailgun (_spf2) necesita la consulta 11, así que el receptor devuelve permerror.
  • El correo del último include ni siquiera llega a evaluarse.

Así que el mismo registro pasa para algunos remitentes y falla para otros. Por eso los problemas de "too many lookups" (demasiadas consultas) suelen aparecer como que el correo de una herramienta falla DMARC mientras todo lo demás se ve bien. Un verificador estático que cuenta el árbol completo, como el script de abajo, informa 13 sin importar qué servidor envió el mensaje. En cualquier caso, no puedes fiarte de un registro con más de 10.

Cuenta tu propio registro

Ejecuta esto en cualquier equipo con Python 3 y dig. Imprime el árbol y el 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. O usa nuestro verificador de SPF, que hace el mismo conteo sin terminal.

Otros dos límites de la misma sección del RFC suelen tomar a la gente por sorpresa:

  • Consultas vacías. El RFC 7208 dice que las implementaciones "SHOULD limit 'void lookups' to two" (DEBERÍAN limitar las "consultas vacías" a dos), es decir, consultas que no devuelven registros o que apuntan a un dominio inexistente. Un include que apunta a un proveedor que dejaste de usar, cuyo registro ya se borró, gasta una de ellas.
  • El mecanismo mx. Cada término mx cuenta como una consulta, y los hosts MX que devuelve no pueden resolver a más de 10 direcciones. ptr está marcado como "do not use" (no usar) en el RFC.

Y uno que no es un límite de consultas, pero produce el mismo permerror: publicar dos registros SPF separados en un mismo dominio. Combínalos en uno.

Cómo volver a estar por debajo de 10

Ve en este orden. Los dos primeros pasos arreglan la mayoría de los registros sin mantenimiento posterior.

1. Quita los include que no hacen nada por ti

SPF comprueba el dominio del remitente del sobre (el Return-Path, o MAIL FROM), no la dirección From que ven tus destinatarios. Muchas plataformas de correo ponen por defecto su propio dominio de rebotes en el remitente del sobre. Si la tuya lo hace, los receptores comprueban SPF contra el dominio de la plataforma y el include de tu registro nunca se consulta.

Para comprobarlo, envíate un mensaje a través de cada plataforma y mira el encabezado Return-Path:

Si el Return-Path muestra... ¿Necesitas el include?
bounce@yourdomain.com o un subdominio tuyo Sí, SPF se comprueba contra tu dominio
bounces+123@em.platform.com o algo similar No, quítalo. La alineación DMARC viene de DKIM

El segundo caso solo funciona si la plataforma firma DKIM con tu dominio, así que confírmalo con nuestro verificador de DKIM antes de borrar nada. Borra también los include de herramientas que ya no usas. Los include viejos son la fuente más común de consultas vacías.

2. Mueve remitentes a subdominios

Cada subdominio tiene su propio registro SPF y su propio presupuesto de 10. Pon el marketing en news.tudominio.com y el soporte en help.tudominio.com, configura la plataforma para usar ese subdominio como dominio de return-path personalizado, y tu registro raíz solo tendrá que cubrir tus buzones. La alineación DMARC sigue funcionando, porque la alineación relajada (la predeterminada) considera alineados los subdominios del mismo dominio organizacional.

3. Reemplaza las consultas de nombres de host por rangos de IP que controlas

Un a: o un mx que apunta a tu propio servidor cuesta una consulta cada vez. Si la IP es fija y es tuya, ip4:203.0.113.10 no cuesta nada.

4. Aplana, con cuidado

El aplanamiento de SPF reemplaza los include por las IP a las que resuelven en ese momento. Te deja por debajo del límite de forma fiable y queda desactualizado de forma igual de fiable, porque los proveedores cambian sus rangos sin avisarte. Si aplanas, hazlo con un servicio o un script programado que vuelva a resolver y publicar, y no aplanes proveedores como Salesforce, cuyo registro usa una macro exists:. Eso no es una lista de IP, así que no hay nada que aplanar.

Un arreglo, de principio a fin

Esta es una empresa hipotética que usa los costos medidos en la tabla de arriba. Sus buzones están en Google Workspace, el marketing sale por SendGrid, las notificaciones del producto por Mailgun, y ventas y soporte usan Salesforce y Zendesk:

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

Uno de más. Dos cambios lo bajan sin aplanar nada:

  1. Las notificaciones del producto pasan a notify.example.com, con Mailgun configurado para usar ese subdominio en el remitente del sobre. El subdominio tiene su propio registro, v=spf1 include:mailgun.org ~all, que cuesta 5 de sus propias 10.
  2. El registro raíz quita include:mailgun.org y baja a 6.

Eso deja cuatro consultas de margen en el dominio raíz para la próxima herramienta en la que alguien se registre, y mantiene los include anidados de Mailgun en un lugar donde no pueden empujar nada más por encima del límite.

Después del arreglo

Vuelve a contar y luego envía una prueba por cada plataforma que uses y revisa Authentication-Results buscando spf=pass. Recuerda que SPF es una de tres comprobaciones. DMARC pasa si SPF o DKIM pasa y está alineado, así que una buena configuración de DKIM es lo que evita que un problema temporal de SPF se convierta en un problema de entrega. Nuestro generador de SPF arma un registro nuevo si prefieres empezar de cero en lugar de editar el viejo.

El registro que tienes hoy se armó un proveedor a la vez. Cuéntalo cada vez que agregues uno.

Preguntas frecuentes

¿Qué mecanismos de SPF cuentan para el límite de 10 consultas DNS?

Según el RFC 7208, los mecanismos include, a, mx, ptr y exists y el modificador redirect cuentan cada uno como una consulta, y las consultas dentro de los registros incluidos también cuentan. Los mecanismos ip4, ip6 y all no cuentan, por eso reemplazar nombres de host por rangos de IP reduce el total.

¿Qué pasa cuando un registro SPF supera las 10 consultas?

El servidor receptor debe devolver un resultado permerror en lugar de pass o fail. Como el límite se aplica durante la evaluación, el correo que coincide con un mecanismo temprano puede pasar igual, mientras que el de un remitente listado más adelante falla, y eso hace que el problema parezca intermitente.

¿El aplanamiento de SPF (SPF flattening) es una buena solución?

Funciona, pero es frágil. El aplanamiento reemplaza los include por los rangos de IP a los que resuelven en ese momento, así que cuando un proveedor cambia sus IP tu registro queda desactualizado sin avisar. Úsalo solo con un servicio o un script que vuelva a aplanar automáticamente, y antes intenta quitar los include innecesarios.

¿Necesito un include por cada plataforma de correo que uso?

Solo para las plataformas que envían con tu dominio en el remitente del sobre (Return-Path). Muchas plataformas ponen ahí su propio dominio de rebotes; en ese caso SPF se comprueba contra su dominio, no el tuyo, y tu include no hace nada. Esas plataformas dependen de DKIM para la alineación DMARC.

Verifica correos por 39,00 USD/mes, sin cortes

Comprobación SMTP real del buzón. Sin créditos ni cobro por correo.

Empezar

Leer el original en inglés