El NXDOMAIN intermitente es el tipo de incidencia que hace que operadores experimentados empiecen a decir “está embrujado” en reuniones serias. Un minuto tu nombre resuelve; al siguiente la misma consulta desde el mismo cliente devuelve NXDOMAIN, y tu monitorización parece un sismógrafo.
Esto no suele ser “DNS caído”. Es DNS haciendo exactamente lo que, por accidente, le dijiste que hiciera. BIND9 es especialmente bueno en esto: una configuración puede parecer limpia, pasar named-checkconf, servir la mayoría de las consultas correctamente y aun así fabricar NXDOMAIN en ráfagas — porque el caché, las views, los forwarders y DNSSEC mantienen estado de formas que la gente subestima.
Qué significa realmente NXDOMAIN intermitente
NXDOMAIN es una declaración específica: “el nombre no existe”. No es “no puedo alcanzar un upstream”. No es “timeout”. No es “tu paquete fue descartado”. Por eso NXDOMAIN intermitente es tan revelador: algo, en algún lugar, tuvo suficiente confianza para afirmar la no existencia.
Cuando BIND devuelve NXDOMAIN, suele encajar en una de estas categorías:
- NXDOMAIN autoritativo: BIND es autoritativo para la zona y el nombre realmente no existe (o tu archivo de zona dice que no).
- Respuesta negativa en caché: BIND aprendió previamente NXDOMAIN (o NODATA) y lo guardó en caché. Ahora lo repite.
- NXDOMAIN generado por política: Response Policy Zones (RPZ), views, ACLs o lógica especial causan un resultado tipo NXDOMAIN.
- NXDOMAIN proporcionado por forwarder: Tu forwarder dice NXDOMAIN y BIND le da crédito (a veces de más).
- Comportamiento límite de DNSSEC: Típicamente los fallos de DNSSEC son SERVFAIL, pero malas interpretaciones y comportamiento upstream pueden llevar a resultados parecidos a NXDOMAIN, especialmente cuando mezclas validación y forwarders.
La parte “intermitente” suele venir de estados que cambian debajo de ti:
- Entradas negativas de caché que expiran en distintos momentos (SOA MINIMUM / TTL negativo, comportamiento de RFC 2308).
- Múltiples resolutores o nodos anycast con contenidos de caché divergentes.
- Views que seleccionan datos distintos según la IP de origen, EDNS Client Subnet o clave TSIG.
- Forwarders que devuelven respuestas inconsistentes (o uno está roto y se elige a veces).
- Propagación DNS o diferencias temporales en transferencias de zona.
- Diferencias en tamaño/fragmentación de paquetes que afectan solo a respuestas firmadas con DNSSEC, forzando TCP para algunos clientes y no para otros.
Si intentas “arreglar NXDOMAIN intermitente” reiniciando named hasta que pare, no lo estás arreglando—estás jugando a la ruleta del caché. Este es de esos problemas donde o lo instrumentas y razonas, o donas tiempo al vacío.
Guía rápida de diagnóstico
Haz esto en orden. No improvises. El objetivo es identificar rápidamente el origen del NXDOMAIN: autoritativo, caché, política o upstream.
1) Confirma qué estás recibiendo realmente (y de dónde)
- Consulta el resolutor sospechoso directamente (no vía el stub de tu SO).
- Captura las banderas de la respuesta:
aa,ra,ad, y el SOA en la sección AUTHORITY. - Compara con un resolutor conocido bueno (otro recursivo o otra instancia de BIND).
2) Decide: ¿autoritativo o recursivo?
- Si el servidor responde con
aa, estás en territorio autoritativo: contenidos de zona, transferencias y views. - Si responde sin
aapero conra, estás en territorio recursivo: caché, forwarders, validación DNSSEC y política.
3) Revisa caché negativa y política antes de tocar DNSSEC
- El caché negativo es la causa principal de “aparece y desaparece”.
- Desajustes RPZ/view pueden parecer aleatorios cuando los clientes provienen de diferentes pools NAT o direcciones IPv6.
4) Valida la ruta upstream
- Si usas forwarders, prueba cada forwarder individualmente para el nombre que falla.
- Ejecuta
dig +tracedesde un host que no haga forwarding para ver qué piensa el mundo.
5) Solo entonces investiga DNSSEC/EDNS/MTU extraños
- Si las fallas se correlacionan con zonas firmadas por DNSSEC y tamaño UDP, sospecha fragmentación o middleboxes rotos.
Idea parafraseada de Werner Vogels (CTO de Amazon): “Si lo construyes, lo operas”. Si DNS es “de otra persona”, seguirás heredando fallos misteriosos.
La configuración que parece correcta (y por qué engaña)
Aquí está la trampa: BIND tiene suficientes perillas para que dos modelos mentales distintos encajen en la misma configuración. Una persona piensa que montó un resolutor recursivo puro. Otra piensa que es una “cache con forwarders”. Alguien más cree que las views son solo para zonas internas con split-horizon. Y alguien silenciosamente añadió RPZ por “seguridad”.
Todo puede parecer que funciona—hasta que algunos nombres empiezan a tambalearse.
Una configuración clásica de “parece correcta” que genera NXDOMAIN intermitente tiene estos ingredientes:
- Forwarders con comportamiento mixto: un forwarder es un appliance corporativo que reescribe DNS, otro es un resolutor normal. BIND alterna o hace failover.
- Views: clientes internos obtienen una view, clientes VPN otra, y clientes IPv6 caen accidentalmente en la view “por defecto”.
- Caché negativo habilitado (por diseño) con un TTL negativo largo debido al SOA MINIMUM de una zona o una lectura errónea de la semántica de RFC 2308.
- Ajustes de caché obsoletos (o su ausencia) causando diferencias durante caídas parciales del upstream.
- RPZ o “listas de bloqueo” que generan NXDOMAIN para un subconjunto de consultas según QNAME, client subnet o view.
- Múltiples instancias de named detrás de un VIP/anycast con cachés y tiempos de actualización no coordinados.
BIND es determinista. Tu entorno no lo es.
Broma 1: DNS es el único sistema donde “no existente” puede ser almacenado en caché como una característica de rendimiento. Realidad, pero con TTLs.
Modos de fallo que producen NXDOMAIN intermitente
1) Caché negativo: NXDOMAIN que persiste después de arreglar el registro
El caché negativo no es una peculiaridad de implementación; es parte de DNS. Cuando un resolutor aprende que foo.example.com no existe, puede almacenar ese hecho en caché. ¿Cuánto tiempo? Basado en el SOA de la zona y las reglas de caché negativa del RFC 2308. En la práctica, los operadores se queman cuando:
- Crean un registro poco después de consultarlo (o después de que alguna comprobación automatizada lo consultara antes de que terminara la provisión).
- El resolutor almacenó NXDOMAIN con un TTL negativo más largo de lo esperado.
- Sólo “arreglaron” un servidor autoritativo y otro todavía devuelve NXDOMAIN a veces.
La intermitencia viene de qué instancia de resolutor o qué caché alcanzas, o del TTL negativo expirando en momentos distintos a lo largo de una flota.
2) Views: datos de zona correctos, clientes equivocados
Las views son poderosas y afiladas. Seleccionan distintos datos de zona y opciones según la identidad del cliente (IP de origen, TSIG, coincidencia ACL). Un fallo sutil: los clientes IPv6 no coinciden con las ACL previstas y caen en una view por defecto que no tiene la zona interna cargada. Reciben NXDOMAIN. IPv4 parece bien. Esto puede sentirse intermitente cuando clientes dual-stack alternan entre v4 y v6, o cuando pools NAT distribuyen clientes entre rangos de origen múltiples.
3) Forwarders: “forward first” enmascarando rarezas del upstream
Si usas forward first;, BIND intentará los forwarders y, si fallan (timeout/REFUSED), volverá a la recursión completa. Eso suena resiliente. También es fuente de inconsistencia:
- Si un forwarder devuelve NXDOMAIN rápidamente (aunque sea incorrecto), BIND lo acepta y no hará recursión.
- Si un forwarder hace timeout, BIND puede recursar y encontrar la respuesta correcta.
- Así el mismo nombre puede alternar entre NXDOMAIN y NOERROR dependiendo de la salud del forwarder.
En entornos regulados, los forwarders también pueden aplicar sufijos de búsqueda “útiles”, split-horizon o listas de bloqueo. Si esa política cambia, tu BIND se convierte en el mensajero y recibe la culpa.
4) RPZ: NXDOMAIN por política que es difícil de notar
RPZ puede reescribir respuestas a NXDOMAIN, NODATA, CNAME a una walled-garden, o algo más. Si RPZ se aplica solo en una view, solo algunos clientes ven NXDOMAIN. Si las actualizaciones de RPZ se tiran de forma asincrónica, un subconjunto de tus resolutores puede tener la política cargada mientras otros no. Felicitaciones: NXDOMAIN intermitente.
5) Inconsistencia autoritativa: propagación parcial, transferencias rotas o suposiciones de “master oculto”
Si BIND es autoritativo (o tienes servidores autoritativos en otro lugar), NXDOMAIN intermitente suele significar que no todos los servidores autoritativos están de acuerdo. Causas comunes:
- Un secundario no está transfiriendo actualizaciones (mismatch TSIG, firewall, problemas de notify).
- Los números de serie no se incrementan de forma fiable.
- Actualizaciones dinámicas (DDNS) escriben en un servidor, pero los secundarios no las recogen, o las views dividen la ruta de actualización.
Los resolutores eligen distintos servidores autoritativos según RTT y caché. Ves “a veces NXDOMAIN”. No es “a veces”. Es “desde ese servidor”.
6) Dominios de búsqueda + ndots: el problema de “yo no pedí ese nombre”
Muchos NXDOMAIN son autoinfligidos por los clientes. Con dominios de búsqueda y ndots, una consulta por api puede convertirse en api.corp.example, api.prod.corp.example, y finalmente api. El resolutor puede almacenar en caché respuestas negativas para esas expansiones. Si tu aplicación solo registra el nombre corto, tus logs DNS muestran un nombre distinto. El informe resultante parece una obra de teatro surrealista.
7) DNSSEC/EDNS/MTU: no generan NXDOMAIN directamente, pero amplifican el caos
Los fallos de DNSSEC suelen aparecer como SERVFAIL en resolutores que validan. Pero DNSSEC afecta tamaños de payload y comportamiento de transporte. Algunos clientes reintentan por TCP; otros no. Algunos middleboxes descartan fragmentos. Un forwarder puede degradar y devolver comportamiento tipo NXDOMAIN para ciertos nombres si su propio motor de validación o política se confunde. La parte intermitente a menudo se correlaciona con:
- Sólo algunas redes con PMTUD roto o reensamblado de fragmentos dañado.
- Sólo algunos nombres firmados por DNSSEC o con respuestas grandes (muchos registros, cadenas RRSIG largas).
- Anycast o flotas multi-resolver donde solo algunos nodos tienen la ruta rota.
Tareas prácticas: comandos, salidas y decisiones (12+)
Estos son los pasos que realmente quiero que la gente ejecute durante un incidente. Cada tarea incluye: comando, qué significa la salida y qué decisión tomar a continuación.
Task 1: Query the resolver directly and read the flags
cr0x@server:~$ dig @127.0.0.1 www.example.com A +noall +answer +authority +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 53188
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; AUTHORITY SECTION:
example.com. 300 IN SOA ns1.example.net. hostmaster.example.com. 2026020401 3600 600 1209600 300
Significado: Estado NXDOMAIN, recursión disponible (ra), no autoritativo (ausencia de aa). Esta es una respuesta recursiva (o reenviada) y el SOA te indica qué zona afirmó la no existencia.
Decisión: Trata primero como problema de caché/forwarder/política. Si hubiera estado aa, pivota a los datos autoritativos y a las transferencias de zona.
Task 2: Compare against a known-good resolver
cr0x@server:~$ dig @9.9.9.9 www.example.com A +noall +answer +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4821
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
www.example.com. 60 IN A 203.0.113.10
Significado: El resolutor público obtiene NOERROR con un registro A. Tu BIND devolviendo NXDOMAIN no es “Internet”. Es tu stack.
Decisión: Investiga caché negativo, views, RPZ y forwarders. No toques la zona autoritativa todavía.
Task 3: See whether your BIND is forwarding and to whom
cr0x@server:~$ sudo named-checkconf -p | sed -n '1,160p'
options {
directory "/var/cache/bind";
recursion yes;
allow-recursion { 10.0.0.0/8; 192.168.0.0/16; };
forwarders { 10.10.10.10; 10.10.10.11; };
forward first;
dnssec-validation auto;
};
zone "corp.example" IN {
type master;
file "/etc/bind/zones/db.corp.example";
};
Significado: Estás reenviando primero a dos forwarders internos. Eso por sí solo puede crear diferencias intermitentes si los forwarders no coinciden o uno está sano.
Decisión: Prueba cada forwarder directamente para el nombre que falla (tarea siguiente). Si los forwarders devuelven NXDOMAIN, BIND solo es el mensajero.
Task 4: Query forwarders individually
cr0x@server:~$ dig @10.10.10.10 www.example.com A +noall +answer +authority +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 30211
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
example.com. 600 IN SOA ns1.example.net. hostmaster.example.com. 2026020401 3600 600 1209600 600
cr0x@server:~$ dig @10.10.10.11 www.example.com A +noall +answer +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6114
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
www.example.com. 60 IN A 203.0.113.10
Significado: Tus forwarders no están de acuerdo. Con forward first, tu BIND puede aceptar a veces NXDOMAIN de un forwarder y otras veces obtener la respuesta correcta del otro.
Decisión: Arregla o elimina el forwarder con mal comportamiento. Si no puedes, considera forward only; (para política estricta) o deja de reenviar y recursa tú mismo (para corrección), pero no mezcles “a veces política” con “a veces realidad”.
Task 5: Check if the NXDOMAIN is being cached (negative cache)
cr0x@server:~$ sudo rndc dumpdb -cache
Dumping caches.
cr0x@server:~$ sudo grep -n "www.example.com" /var/cache/bind/named_dump.db | head
21483;www.example.com. 300 negative
21484;www.example.com. 300 IN SOA example.com. hostmaster.example.com. 2026020401 3600 600 1209600 300
Significado: BIND tiene una entrada negativa en caché para www.example.com con 300 segundos restantes.
Decisión: Si sabes que el nombre existe ahora, vacíalo para dejar de servir NXDOMAIN obsoleto y luego arregla la causa upstream que inyectó NXDOMAIN.
Task 6: Flush a single name (surgical, not “flush everything”)
cr0x@server:~$ sudo rndc flushname www.example.com
flushed
Significado: Elimina datos en caché para ese nombre (incluido caché negativo), forzando una re-resolución.
Decisión: Reconsulta inmediatamente. Si vuelve NXDOMAIN, no era “caché obsoleto”—es upstream o política.
Task 7: Check if the NXDOMAIN is being cached (negative cache)
cr0x@server:~$ sudo named-checkconf -p | grep-n "response-policy" -n
42: response-policy { zone "rpz-block"; };
cr0x@server:~$ dig @127.0.0.1 www.example.com A +noall +answer +authority
example.com. 300 IN SOA ns.rpz.local. hostmaster.rpz.local. 2026020401 3600 600 1209600 300
Significado: El SOA en la sección de autoridad proviene de un dominio relacionado con RPZ, no de example.com. Eso es una prueba contundente: la política generó este “NXDOMAIN”.
Decisión: Inspecciona el contenido de la zona RPZ y la canalización de actualización. Decide si este nombre debe bloquearse. Si no, arregla la fuente RPZ o crea excepciones de política.
Task 8: Validate whether views are selecting different zone data
cr0x@server:~$ sudo named-checkconf -p | sed -n '1,220p' | grep -n "view\|match-clients\|zone \"corp.example\""
61:view "internal" {
62: match-clients { 10.0.0.0/8; 192.168.0.0/16; };
80: zone "corp.example" { type master; file "/etc/bind/zones/db.corp.example"; };
95:};
97:view "external" {
98: match-clients { any; };
112: zone "corp.example" { type master; file "/etc/bind/zones/db.corp.example.external"; };
130:};
Significado: Clientes distintos pueden obtener versiones diferentes de la misma zona. Eso no es automáticamente incorrecto. Es automáticamente arriesgado.
Decisión: Confirma qué clientes coinciden con qué view (tareas siguientes) y si el archivo de zona “external” omite intencionalmente nombres que ahora necesitan los clientes VPN/cloud.
Task 9: Query from different source addresses to reproduce view selection
cr0x@server:~$ dig @10.0.0.53 app.corp.example A +noall +answer +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15054
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
app.corp.example. 30 IN A 10.20.30.40
cr0x@server:~$ dig @198.51.100.53 app.corp.example A +noall +answer +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 4490
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
Significado: Mismo software resolutor, distinta dirección/ruta, distinta respuesta. Eso suele ser views o política, no “azar DNS”.
Decisión: Decide si app.corp.example debe ser visible externamente. Si sí, arregla los datos de zona en la view externa o las reglas de match-clients.
Task 10: Verify authoritative consistency with +trace
cr0x@server:~$ dig +trace www.example.com A
; <<>> DiG 9.18.24 <>> +trace www.example.com A
;; Received 811 bytes from 127.0.0.1#53(127.0.0.1) in 0 ms
example.com. 172800 IN NS ns1.example.net.
example.com. 172800 IN NS ns2.example.net.
;; Received 525 bytes from 192.0.2.53#53(a.root-servers.net) in 19 ms
www.example.com. 60 IN A 203.0.113.10
;; Received 116 bytes from 203.0.113.53#53(ns1.example.net) in 24 ms
Significado: La ruta autoritativa devuelve NOERROR. Si tu resolutor devuelve NXDOMAIN, el problema está entre tu resolutor y la autoridad: forwarders, caché, política o ruta de resolución rota.
Decisión: Si hay forwarders involucrados, arréglalos. Si no, inspecciona los logs del resolutor y el comportamiento del caché.
Task 11: Turn on targeted query logging (temporarily) to see the source of NXDOMAIN
cr0x@server:~$ sudo rndc querylog
query logging is now on
cr0x@server:~$ sudo journalctl -u bind9 -n 20 --no-pager
Feb 04 11:12:01 dns1 named[1234]: client @0x7f2a1c0 10.1.2.3#55214 (www.example.com): query: www.example.com IN A +E(0)K (10.10.10.10)
Feb 04 11:12:01 dns1 named[1234]: client @0x7f2a1c0 10.1.2.3#55214 (www.example.com): forwarding failed, response NXDOMAIN from 10.10.10.10
Significado: El log muestra explícitamente el reenviado y el upstream que devolvió NXDOMAIN.
Decisión: Deja de debatir. Arregla 10.10.10.10 o elimínalo. Luego apaga el registro de consultas; es ruidoso en producción.
Task 12: Check for SERVFAILs masked by client retries (and transport issues)
cr0x@server:~$ dig @127.0.0.1 dnskey example.com +dnssec +noall +comments +answer
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38712
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
Significado: ad indica datos validados (cuando el cliente lo pidió y el resolutor valida). Si nunca ves ad donde lo esperas, la validación puede estar desactivada o fallando.
Decisión: Si DNSSEC está en juego y las fallas se correlacionan con redes específicas, inspecciona EDNS size y la caída a TCP (tareas siguientes). Aunque no provoque NXDOMAIN directamente, puede desencadenar comportamientos de reintento distintos que parezcan “intermitentes”.
Task 13: Check EDNS UDP size and force TCP to test fragmentation hypotheses
cr0x@server:~$ dig @127.0.0.1 www.example.com A +dnssec +bufsize=4096 +noall +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19640
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
cr0x@server:~$ dig @127.0.0.1 www.example.com A +tcp +noall +comments +answer
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28640
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
www.example.com. 60 IN A 203.0.113.10
Significado: Si UDP falla a veces pero TCP siempre funciona, probablemente tienes un problema de MTU/ruta o fragmentación entre clientes y resolutor, o entre resolutor y upstream.
Decisión: Reduce el tamaño UDP anunciado en el resolutor (o arregla la red). No “resuelvas” desactivando DNSSEC por todas partes a menos que disfrutes de futuros incidentes.
Task 14: Inspect BIND statistics for spikes in NXDOMAIN/negative answers
cr0x@server:~$ sudo rndc stats
Statistics dump file written to /var/cache/bind/named.stats
cr0x@server:~$ sudo sed -n '1,120p' /var/cache/bind/named.stats
+++ Statistics Dump +++
++ Incoming Requests ++
18452 QUERY
++ Outgoing Requests ++
10211 QUERY
++ Name Server Statistics ++
1423 NXDOMAIN
211 SERVFAIL
Significado: Altos conteos de NXDOMAIN pueden ser normales (typos, dominios de búsqueda), o pueden ser tu incidente. Combínalo con registro de consultas o un filtro por qname para ver qué nombres dominan.
Decisión: Si los picos de NXDOMAIN se vinculan a un dominio/servicio crítico, céntrate ahí. Si son amplios, sospecha forwarder/política/view.
Task 15: Verify zone file correctness if authoritative
cr0x@server:~$ sudo named-checkzone corp.example /etc/bind/zones/db.corp.example
zone corp.example/IN: loaded serial 2026020401
OK
Significado: La zona se parsea y carga; el serial es visible.
Decisión: Si ocurre NXDOMAIN intermitente y eres autoritativo, compara seriales entre todas las autoridades. Un secundario desfasado es un culpable habitual.
Task 16: Confirm secondaries have the same serial (authoritative consistency)
cr0x@server:~$ dig @ns1.corp.example corp.example SOA +noall +answer
corp.example. 300 IN SOA ns1.corp.example. hostmaster.corp.example. 2026020401 3600 600 1209600 300
cr0x@server:~$ dig @ns2.corp.example corp.example SOA +noall +answer
corp.example. 300 IN SOA ns1.corp.example. hostmaster.corp.example. 2026020317 3600 600 1209600 300
Significado: ns2 está atrasado (serial más antiguo). Los resolutores que golpeen ns2 pueden obtener NXDOMAIN para nombres añadidos recientemente.
Decisión: Arregla transferencias de zona (TSIG, allow-transfer, notify, firewall). No lo soluciones con TTLs bajos; eso solo hará que el dolor llegue más rápido.
Errores comunes: síntoma → causa raíz → solución
Esta es la sección que reconocerás a mitad de un incidente, porque ya habrás visto al menos dos de estos en tu carrera. Si no, felicidades por tu vida encantada.
1) “A mí me resuelve pero a los usuarios no”
Síntoma: El personal TI en la red corporativa obtiene NOERROR; usuarios remotos/VPN/móviles obtienen NXDOMAIN.
Causa raíz: Views o split-horizon. Los usuarios remotos caen en una view distinta (a menudo por direcciones IPv6 o pools NAT distintos), que carece del registro o tiene RPZ aplicada.
Solución: Audita las ACLs de match-clients para v4 y v6, y asegura que las zonas/políticas correctas existan en todas las views previstas. Prueba desde redes representativas, no solo desde el propio servidor DNS.
2) “Añadimos el registro, pero sigue NXDOMAIN a veces”
Síntoma: Tras la provisión, algunos clientes aún obtienen NXDOMAIN durante minutos u horas.
Causa raíz: Caché negativo. El NXDOMAIN se aprendió y almacenó antes de que el registro existiera, y el TTL negativo es más largo de lo que asumiste.
Solución: Vacía nombres específicos en los resolutores recursivos (rndc flushname) durante cortes urgentes. A largo plazo: reduce TTLs negativos diseñando conscientemente SOA MINIMUM/negative TTL, y evita comprobaciones previas que consulten nombres antes de que existan (o aísla esas comprobaciones a resolutores de staging).
3) “Falla solo los lunes (o aleatoriamente), y reiniciar BIND ayuda”
Síntoma: NXDOMAIN intermitente que “desaparece” tras reiniciar.
Causa raíz: Resetear caché oculta el upstream inconsistente: forwarders que no coinciden, actualizaciones RPZ inconsistentes, o una autoridad fuera de sincronía.
Solución: Deja de reiniciar como cura. Identifica qué upstream generó NXDOMAIN mediante registro de consultas o pruebas a forwarders. Arregla la fuente; entonces los resets de caché serán innecesarios y raros.
4) “Solo algunos registros bajo una zona fallan, otros funcionan”
Síntoma: Un puñado de hostnames NXDOMAIN; otros bajo la misma zona resuelven.
Causa raíz: Wildcards y empty non-terminals, o el registro existe solo en una view/una autoridad. Otra raíz común: creaste registros tipo _service._tcp pero los clientes consultan tipos distintos y surge confusión NODATA/NXDOMAIN.
Solución: Comprueba respuestas autoritativas directamente. Inspecciona archivos de zona por delegaciones, wildcards y nodos faltantes. Verifica que todas las autoridades tengan el mismo serial y datos.
5) “Funciona en IPv4, falla en IPv6”
Síntoma: Clientes dual-stack ven NXDOMAIN intermitente según la pila que usen.
Causa raíz: ACLs de views sin IPv6, diferencias de alcanzabilidad upstream, o ausencia de registros AAAA/glue provocando rutas de resolución distintas.
Solución: Haz las ACLs de views explícitamente dual-stack. Asegura que forwarders y root hints sean accesibles por IPv6 si sirves clientes v6. Prueba con dig -6 y compara.
6) “Sucede solo en algunos dominios públicos”
Síntoma: Un subconjunto de dominios externos devuelve NXDOMAIN desde tu resolutor, pero el resto resuelve.
Causa raíz: Bloqueos RPZ, filtrado DNS upstream, o un forwarder roto que remapea a NXDOMAIN por “seguridad”.
Solución: Identifica si el SOA en la respuesta NXDOMAIN apunta a la zona real o a una zona de política. Si es política, corrige la política. Si es el forwarder, reemplázalo o reconfigúralo. No aceptes “el appliance de seguridad lo dice” sin auditabilidad.
Tres mini-historias corporativas desde el frente
Mini-historia 1: El incidente causado por una suposición errónea
La empresa tenía dos resolutores internos detrás de un balanceador. El equipo asumió que eran “idénticos”, porque se construyeron con la misma automatización. Esa suposición vivió feliz durante meses, como suelen hacerlo las suposiciones.
Entonces lanzó un nuevo servicio interno con un hostname que no existía hasta que la canalización de despliegue lo creó. Un health check —ejecutado temprano— consultó el nombre repetidamente. Por una ventana breve, los resolutores aprendieron NXDOMAIN y lo almacenaron. Poco después, el registro apareció y empezó a resolverse… a veces. Algunos clientes golpeaban el resolutor A (aún con NXDOMAIN en caché), otros el resolutor B (la caché ya había expirado). El on-call lo vio como un despliegue inestable de la app.
Reiniciaron el miembro del pool del balanceador que “parecía malo”. Los síntomas desaparecieron. El postmortem casi terminó allí, que es como se mantiene el mismo incidente en suscripción.
Una semana después, volvió a ocurrir. Esta vez alguien comparó los campos SOA MINIMUM para su zona interna. Un resolutor tenía una versión de zona antigua con un TTL negativo más largo debido a una transferencia secundaria obsoleta. No idénticos. Ni siquiera cercanos cuando importaba.
La solución no fue heroica. Repararon las transferencias, estandarizaron SOA/TTLs negativos y cambiaron el health check de despliegue para que consultara solo después de la creación del registro o consultara un resolutor de staging. La suposición errónea fue “nodos idénticos”. DNS desmonta esa suposición rápido.
Mini-historia 2: La optimización que salió mal
Otra organización se enorgullecía de su “DNS rápido”. Habilitaron forwarders a una capa de caching interna que prometía baja latencia y “filtrado de seguridad”. También pusieron forward first para que BIND recursara si el forwarder tenía problemas. ¿Lo mejor de ambos mundos, no?
Funcionó—hasta que el proveedor del forwarder empujó una actualización de política. Un conjunto de dominios empezó a devolver NXDOMAIN por errores de categorización. Mientras tanto, el cluster de forwarder estaba algo sobrecargado; a veces hacía timeout. En esos casos, BIND volvía a recursar y devolvía la respuesta correcta. Así los usuarios vieron NXDOMAIN intermitente según si el forwarder respondió rápido (mal) o lento (no respondió).
El proveedor insistió en “sin outage”. Sus sistemas estaban arriba. Cierto. Los nombres de los clientes estaban caídos, intermitentemente. El equipo de BIND tuvo que ser el adulto en la sala y demostrar, con logs, que “respuestas rápidas y equivocadas” son peores que “respuestas lentas y correctas”.
Cambiaron temporalmente a forward only para hacer el comportamiento consistente mientras escalaban el problema de política. La consistencia redujo tickets inmediatamente, aunque significara “siempre bloqueado” para esos dominios hasta que la política se corrigiera. Después de arreglado el forwarder, reevaluaron si necesitaban esa capa.
Broma 2: Lo único peor que una respuesta DNS lenta es una rápida que está confiada y equivocada.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Una compañía financiera gestionaba DNS autoritativo para algunas zonas internas y una pública para endpoints cliente. Tenían una rutina: cada cambio de zona requería un incremento de serial, named-checkzone y una verificación rápida del serial SOA en todas las autoridades. Sin excepciones. Era impopular entre quienes creen que DNS es “solo un archivo de texto”.
Una tarde, una petición de cambio añadió un nuevo endpoint cliente. El primario se actualizó bien. Un secundario no. Pero como el equipo siempre comprobaba los seriales SOA, lo detectaron en minutos. Aún no habían recibido una sola queja de cliente.
La causa fue mundana: una regla de firewall había sido “limpiada” la noche anterior, y TCP/53 para transferencias de zona fue eliminada entre el primario y ese secundario. El secundario seguía sirviendo la zona vieja. Si esto hubiese llegado a clientes, habrían visto NXDOMAIN intermitente según qué servidor autoritativo escogiera su resolutor.
El equipo restauró la regla de firewall, confirmó la transferencia y el registro se hizo globalmente consistente. La práctica aburrida—comprobación de seriales—previno un incidente visible para clientes. En ops, aburrido a menudo es otra palabra para “efectivo”.
Hechos interesantes y contexto histórico
- NXDOMAIN está estandarizado: Es el RCODE 3 de DNS, que significa “Name Error”, y es distinto de “sin datos” (NOERROR con respuesta vacía).
- El caché negativo no siempre fue común: RFC 2308 formalizó el comportamiento de caché negativa para reducir consultas repetidas innecesarias por nombres inexistentes.
- SOA MINIMUM fue reutilizado: Históricamente, SOA MINIMUM se usaba como TTL por defecto para registros; luego se asoció a la semántica de TTL negativo.
- BIND ha sido la implementación de referencia por décadas: El comportamiento de BIND influyó en expectativas operativas de la industria, para bien y ocasionalmente para “¿por qué hace eso?”.
- Split-horizon DNS es anterior a la nube: Las empresas usan views/split-horizon desde mucho antes de que Kubernetes hiciera que todos descubrieran servicios a la mala.
- RPZ fue creada para política a escala: Permite inyectar modificaciones de respuesta sin cambiar zonas autoritativas, lo que es poderoso y fácil de abusar.
- DNSSEC aumentó el tamaño de las respuestas: La validación introduce registros adicionales (RRSIG, DNSKEY, DS) que incrementan el tamaño de respuesta y hacen visibles problemas de transporte/ruta.
- Los resolutores prefieren UDP hasta que no pueden: DNS comúnmente empieza en UDP/53; existe fallback a TCP, pero las pilas cliente y los middleboxes varían ampliamente.
- “Autoritativo” es por zona, no por servidor: Un servidor puede ser autoritativo para una zona y recursivo para todo lo demás, que es una fuente clásica de confusión al diagnosticar.
Listas de verificación / plan paso a paso
Checklist A: Determinar de dónde viene NXDOMAIN
- Ejecuta
dig @your-resolver name type +noall +answer +authority +comments. - Registra: estado, presencia de
aa, presencia dera, y el nombre propietario del SOA en AUTHORITY. - Si el SOA coincide con la zona real: probablemente NXDOMAIN autoritativo genuino o cacheado desde la autoridad.
- Si el SOA parece una zona RPZ/política: NXDOMAIN generado por política.
- Si usas forwarders: consulta cada forwarder directamente y compara.
Checklist B: Arreglar sin daños colaterales
- Vacía solo el/los nombre(s) afectados en resolutores recursivos:
rndc flushname. - Si hay inconsistencia autoritativa: verifica seriales SOA en todos los servidores autoritativos y repara transferencias.
- Si views: asegúrate de que el registro exista en las views previstas y que las ACLs incluyan rangos cliente IPv4 e IPv6.
- Si los forwarders no coinciden: elimina el malo o arregla su política/zona. No dejes “a veces equivocado” en rotación.
- Si RPZ: confirma si es un bloqueo verdadero; añade excepciones si hace falta; arregla la sincronización del feed.
Checklist C: Hacer difícil la regresión
- Añade monitorización sintética que consulte cada nodo del resolutor directamente, no solo el VIP.
- Alerta por aumentos súbitos de NXDOMAIN para nombres críticos específicos (no por volumen global de NXDOMAIN).
- Seguimiento independiente de la salud de forwarders y eliminación automática si devuelven nonsense para un dominio canario.
- Para zonas autoritativas, automatiza comprobaciones de paridad de serial SOA entre todas las autoridades.
- Mantén definiciones de view mínimas. Cada view es una rama en tu árbol de incidentes.
Preguntas frecuentes (FAQ)
1) ¿Por qué NXDOMAIN es intermitente en lugar de consistentemente incorrecto?
Porque DNS es distribuido y cacheado. Diferentes resolutores, distintos estados de caché, distintos upstreams, distintas views. Tu sistema puede ser “consistentemente inconsistente”.
2) ¿Cómo puedo saber si BIND es autoritativo para una zona?
Consulta y busca la bandera aa en la respuesta. También inspecciona named-checkconf -p para la definición de la zona. Si es type master o type slave, es autoritativo para esa zona.
3) ¿Cuál es la diferencia entre NXDOMAIN y NODATA?
NXDOMAIN significa que el nombre no existe en absoluto. NODATA es NOERROR pero con respuesta vacía para ese tipo (por ejemplo, el nombre existe pero no tiene registro A). Ambos pueden cachearse negativamente y ambos pueden romper aplicaciones de distintas maneras.
4) ¿Puede DNSSEC causar NXDOMAIN?
Los fallos de validación DNSSEC típicamente producen SERVFAIL en resolutores que validan. Pero DNSSEC aumenta el tamaño y la complejidad de las respuestas, lo que puede desencadenar problemas de transporte o rarezas en forwarders que aparecen como respuestas equivocadas, incluyendo NXDOMAIN desde motores de política upstream.
5) ¿Debo usar forward first o forward only?
Si necesitas que los forwarders apliquen política estricta, usa forward only y acepta que la política es la fuente de la verdad. Si quieres corrección e independencia, no reenvíes: recursa directamente. forward first puede crear comportamiento inconsistente cuando los forwarders son inestables o están equivocados.
6) ¿Vaciar la caché es una solución válida?
Vaciar un nombre específico es una mitigación válida cuando el caché negativo es el problema inmediato. Vaciar toda la caché es un instrumento contundente que oculta causas raíz, incrementa carga upstream y suele empeorar la próxima falla.
7) ¿Cómo demuestro que es un problema de RPZ?
Mira el SOA en la sección AUTHORITY de la respuesta NXDOMAIN; un NXDOMAIN por política a menudo apunta a un SOA controlado por RPZ. También busca response-policy en la configuración efectiva e inspecciona el contenido de la zona RPZ.
8) ¿Por qué solo algunos clientes golpean la view equivocada?
Porque las ACLs de match-clients a menudo no incluyen todos los rangos reales de origen de clientes (especialmente IPv6), o porque el tráfico viene por NAT, pools VPN o split tunneling. Clientes que crees “internos” pueden no parecer internos al servidor DNS.
9) ¿Cuál es la forma más rápida de aislar un forwarder roto?
Consulta cada forwarder directamente para un nombre que falle y para un nombre canario conocido y bueno, de forma consecutiva. Si uno devuelve NXDOMAIN mientras otros devuelven NOERROR, es el culpable. Confírmalo luego con registro de consultas en BIND.
10) ¿Cómo evito que este tipo de incidentes se repita?
Monitorea el comportamiento por nodo del resolutor, controla expectativas de TTL negativos, mantiene views/políticas explícitas y auditadas, y prueba forwarders como dependencias—porque lo son.
Conclusión: siguientes pasos que sí puedes hacer
El NXDOMAIN intermitente no es un capricho místico del DNS. Casi siempre es una de cuatro cosas: caché negativo, views, forwarders o política (RPZ). DNSSEC y problemas de transporte de red son cómplices frecuentes, no suelen ser el autor original del NXDOMAIN.
Pasos prácticos:
- Elige un nombre que falle y reproduce la consulta con
digdirectamente contra tu resolutor. Guarda la salida con banderas y SOA. - Consulta cada forwarder individualmente. Si no coinciden, encontraste tu “intermitente”.
- Vuelca la caché y confirma si existe una entrada negativa. Vacía el nombre específico para mitigar.
- Inspecciona views y configuración RPZ en la configuración renderizada (
named-checkconf -p), no en la memoria de alguien. - Si eres autoritativo, verifica la paridad de seriales SOA entre todos los servidores autoritativos antes de culpar a los resolutores.
- Después del incidente: añade comprobaciones DNS por nodo y una consulta canaria que nunca deba ser NXDOMAIN, y alerta cuando lo sea.
Haz eso, y la próxima vez que alguien diga “DNS está inestable”, podrás responder con pruebas, no con sensaciones.