{"id":15707,"date":"2026-09-06T01:21:46","date_gmt":"2026-09-05T23:21:46","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/dns-delegation-serial-ttl-auditor\/"},"modified":"2026-09-17T20:56:55","modified_gmt":"2026-09-17T18:56:55","slug":"dns-delegation-serial-ttl-auditor","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/","title":{"rendered":"DNS Delegation, Serial &#038; TTL Auditor: asking every nameserver separately"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">A domain usually has two or more nameservers, and a normal lookup asks whichever one answers first. That hides the interesting failures. This check asks a public resolver for the delegation, then puts the same three questions to every nameserver directly: which serial the zone carries, which nameservers the zone itself lists, and which address the domain resolves to. Answers that differ are the finding.<\/p>\n<div style=\"margin-bottom: 14px;\">\n        <label for=\"dnszone-domain\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Domain<\/label><br \/>\n        <input id=\"dnszone-domain\" type=\"text\" value=\"lukaswojcik.com\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; box-sizing: border-box; font-family: monospace;\">\n    <\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.82rem; margin-bottom: 16px;\">From this server: DNS queries only, to public resolvers and to the domain&#039;s own nameservers. No web page is fetched, no cookies are sent, nothing is stored beyond the counter entry: IP address, time and size of the request, for seven days.<\/p>\n<p>    <button id=\"dnszone-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: var(--on-accent, #0b1114); border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Check delegation<\/button><\/p>\n<div data-mp-mask id=\"dnszone-ausgabe\" style=\"margin-top: 22px;\"><\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.8rem; margin: 24px 0 0;\">Limits worth knowing: at most six nameservers are queried, over UDP, and an answer larger than 4 KB is truncated. A server behind a firewall that drops UDP from unknown addresses will look silent here even though it answers resolvers normally.<\/p>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"A domain usually has two or more nameservers, and a normal lookup asks whichever one answers first. That hides the interesting failures. This check asks a public resolver for the delegation, then puts the same three questions to every nameserver directly: which serial the zone carries, which nameservers the zone itself lists, and which address the domain resolves to. Answers that differ are the finding.\",\"label_domain\":\"Domain\",\"datenschutz\":\"From this server: DNS queries only, to public resolvers and to the domain\\u0027s own nameservers. No web page is fetched, no cookies are sent, nothing is stored beyond the counter entry: IP address, time and size of the request, for seven days.\",\"knopf\":\"Check delegation\",\"laeuft\":\"Asking nameservers...\",\"grenze\":\"Limits worth knowing: at most six nameservers are queried, over UDP, and an answer larger than 4 KB is truncated. A server behind a firewall that drops UDP from unknown addresses will look silent here even though it answers resolvers normally.\",\"h_server\":\"Nameservers asked directly\",\"tabelle_hinweis\":\"Authority means the server answered with the AA flag: it holds the zone rather than a cached copy. Serial numbers that differ between servers are the clearest sign that a zone transfer did not arrive.\",\"h_befunde\":\"Findings\",\"sp_ns\":\"Nameserver\",\"sp_ip\":\"Address\",\"sp_erreichbar\":\"Answers\",\"sp_autoritaet\":\"Authority\",\"sp_serial\":\"Serial\",\"sp_a\":\"A record\",\"art_ns\":\"NS\",\"art_a\":\"A\",\"zeile_domain\":\"Domain\",\"zeile_ns\":\"Delegated nameservers\",\"zeile_a\":\"Address\",\"zeile_aaaa\":\"IPv6\",\"zeile_dnssec\":\"DNSSEC\",\"zeile_dauer\":\"Took\",\"zeile_limit\":\"Checks left this hour\",\"wert_ja\":\"yes\",\"wert_nein\":\"no\",\"wert_keine\":\"none\",\"wert_dnssec_validiert\":\"signed and validated\",\"wert_dnssec_ohne\":\"signed, not validated\",\"stufe_hoch\":\"High\",\"stufe_mittel\":\"Medium\",\"stufe_niedrig\":\"Low\",\"stufe_info\":\"Information\",\"stufe_gut\":\"In order\",\"keine_befunde\":\"Nothing to report.\",\"urteil_gut\":\"All nameservers agree.\",\"urteil_warnung\":\"The domain resolves, but the setup has a weak spot.\",\"urteil_kritisch\":\"The nameservers disagree, or one of them does not answer at all.\",\"fehler_kein_token\":\"The check could not be started because reCAPTCHA did not load.\",\"fehler_captcha\":\"reCAPTCHA classified the request as automated. Reloading the page normally helps.\",\"fehler_zu_viele\":\"The limit of {limit} checks per hour for this address has been reached.\",\"fehler_adresse\":\"That domain cannot be used.\",\"fehler_domain\":\"That domain cannot be used.\",\"fehler_kein_dns\":\"No resolver answered for this domain.\",\"fehler_zaehler\":\"The rate counter is unavailable, so nothing was checked.\",\"fehler_pruefdienst\":\"The reCAPTCHA service could not be reached.\",\"fehler_aufbau\":\"The service is not configured correctly. The fault is on this side.\",\"fehler_eingabe\":\"The request could not be read.\",\"fehler_methode\":\"Wrong request method.\",\"fehler_netz\":\"The service could not be reached.\",\"fehler_antwort\":\"The answer could not be read.\",\"fehler_unbekannt\":\"Something went wrong that has no message of its own.\",\"grund_leer\":\"Nothing was entered.\",\"grund_zu_lang\":\"The input is too long.\",\"grund_unlesbar\":\"It does not parse as a domain name.\",\"grund_kein_punkt\":\"The domain needs at least one dot.\",\"grund_hostform\":\"A domain name is expected, not an IP address.\",\"grund_keine_antwort\":\"No resolver answered.\",\"befund_keine_ns\":\"The domain has no nameservers || Either it does not exist, or its delegation is broken. Nothing else can be checked without them.\",\"befund_nur_ein_ns\":\"Only one nameserver is delegated || {name}. Every specification since 1987 asks for at least two, and the reason is simple: one server means one restart, one network fault or one expired certificate away from a domain that no longer resolves.\",\"befund_ns_anzahl\":\"{n} nameservers are delegated || {liste}\",\"befund_cname_am_apex\":\"The domain has a CNAME at its apex || Pointing to {ziel}. That is not allowed: a CNAME cannot coexist with the SOA and NS records every zone apex must carry. Some providers emulate it, which works until something asks the wrong question.\",\"befund_ns_stumm\":\"{name} does not answer || Reason: {grund}. The server is still in the delegation, so resolvers keep asking it and wait for a timeout before trying the next one. Visitors experience that as a slow site, not as an error.\",\"befund_ns_ohne_autoritaet\":\"{name} answers without the authority flag || It replies, but not as a server that holds the zone. Usually that means the zone was removed there while the delegation still points at it.\",\"befund_alle_ns_antworten\":\"All {n} nameservers answer authoritatively || Every one of them holds the zone and says so.\",\"befund_serial_drift\":\"The nameservers carry {n} different serial numbers || {werte}, a difference of {abstand}. Either a zone transfer failed and one server is still holding an older version, or two providers maintain the same zone side by side and count up independently of each other. From the outside the two cannot be told apart, so this is worth a look rather than an alarm: if the NS sets above agree and the addresses match, nothing is reaching visitors differently.\",\"befund_serial_gleich\":\"All {n} nameservers carry serial {serial} || Same version of the zone everywhere.\",\"befund_ns_uneinig\":\"The nameservers list {n} different NS sets || They disagree about who is responsible for the zone. Resolvers may cache either version.\",\"befund_ns_weicht_von_delegation_ab\":\"The zone lists other nameservers than the delegation || In the zone: {zone}. Delegated at the parent: {delegation}. Both are used in practice \u2014 resolvers start from the delegation and may later replace it with the zone\\u0027s own list.\",\"befund_ns_stimmt_ueberein\":\"Delegation and zone list the same {n} nameservers || The parent and the zone agree.\",\"befund_ns_ein_netz\":\"All {n} nameservers sit in {netz} || Two servers in the same network segment fail together. Separate networks, ideally separate providers, are what makes the second server worth having.\",\"befund_ns_mehrere_netze\":\"The nameservers sit in {n} different networks || A network fault takes out one of them, not all.\",\"befund_dnssec_ds\":\"The zone is signed: {n} DS record(s) at the parent || The chain of trust is established, so a manipulated answer can be detected.\",\"befund_ds_ohne_validierung\":\"A DS record exists, but the resolver did not set the AD flag || The signature could not be validated. That points at an expired signature or a key that no longer matches the DS record \u2014 the state in which a validating resolver stops answering for the domain entirely.\",\"befund_kein_dnssec\":\"The zone is not signed || Without DNSSEC an answer cannot be verified. That is still the common case, and it is a deliberate choice for many domains.\",\"befund_kein_a\":\"The domain has no A record || It may still work through a subdomain, but the bare name does not resolve to an address.\",\"befund_kein_aaaa\":\"The domain has no AAAA record || It is reachable over IPv4 only.\",\"befund_mit_aaaa\":\"The domain has {n} AAAA record(s) || Reachable over IPv6 as well.\",\"befund_ttl_kurz\":\"The {art} record has a TTL of {ttl} seconds || Short TTLs make changes take effect quickly and cost a lookup for almost every visit. Useful during a migration, expensive as a permanent setting.\",\"befund_ttl_lang\":\"The {art} record has a TTL of {ttl} seconds ({stunden} hours) || A change then takes that long to reach everyone. Before any planned move the value belongs down to a few minutes, well in advance.\",\"befund_soa\":\"SOA: primary {primaer}, serial {serial}, refresh {refresh}, retry {retry}, expire {expire}, minimum {minimum} || The numbers govern how secondaries follow the primary.\",\"befund_soa_expire_kurz\":\"The SOA expire value is {tage} days || If the primary is unreachable for that long, the secondaries stop answering for the zone entirely. A week is the usual floor.\",\"befund_soa_retry_gross\":\"Retry ({retry}) is not smaller than refresh ({refresh}) || Retry is meant for the case where a refresh failed, so a value at or above refresh has no effect.\",\"befund_primaer_nicht_delegiert\":\"The SOA names {primaer} as primary, which is not among the delegated servers || That is the normal shape of a hidden primary: it holds the zone, the delegated servers copy from it, and nobody asks it directly.\"};<\/p>\n<p>    var ENDPUNKT = '\/api\/lw-dnszone.php';\n    var SITEKEY = '6LcrPkEtAAAAAPo1QCOf-IIM2fCL0UfdJz4y2iSY';\n    var STUFEN = ['hoch', 'mittel', 'niedrig', 'info', 'gut'];<\/p>\n<p>    function liste(w) { return Array.isArray(w) ? w : []; }\n    function zahl(w) { return (typeof w === 'number' && isFinite(w)) ? w : null; }\n    function zeichen(w) { return (typeof w === 'string' && w !== '') ? w : null; }\n    function text(schluessel, daten) {\n        var t = T[schluessel];\n        if (typeof t !== 'string') { return null; }\n        return t.replace(\/\\{([a-z_0-9]+)\\}\/g, function (m, k) {\n            var w = (daten && daten[k] !== undefined && daten[k] !== null) ? daten[k] : null;\n            if (w === null) { return m; }\n            if (k === 'art' && T['art_' + w]) { return T['art_' + w]; }\n            return String(w);\n        });\n    }<\/p>\n<p>    function bewerten(antwort) {\n        var a = antwort || {};\n        if (a.fehler) { return { fehler: String(a.fehler), grund: a.grund || null, limit: zahl(a.limit) }; }\n        var befunde = liste(a.befunde).map(function (f) {\n            return { key: String(f.key || ''), stufe: STUFEN.indexOf(f.stufe) === -1 ? 'info' : f.stufe, daten: (f.daten && typeof f.daten === 'object') ? f.daten : {} };\n        });\n        var gruppen = {};\n        STUFEN.forEach(function (s) { gruppen[s] = befunde.filter(function (f) { return f.stufe === s; }); });\n        var server = liste(a.server).map(function (z) {\n            return { name: String(z.name || ''), ip: zeichen(z.ip), erreichbar: z.erreichbar === true, aa: z.aa === true,\n                serial: zahl(z.serial), ns: zahl(z.ns), a: zeichen(z.a) };\n        });\n        return {\n            fehler: null, domain: String(a.domain || ''),\n            urteil: (a.urteil === 'gut' || a.urteil === 'warnung' || a.urteil === 'kritisch') ? a.urteil : 'kritisch',\n            ns: liste(a.ns).filter(function (x) { return typeof x === 'string'; }),\n            adressen: liste(a.a).filter(function (x) { return typeof x === 'string'; }),\n            aaaa: liste(a.aaaa).filter(function (x) { return typeof x === 'string'; }),\n            dnssec: a.dnssec === true, ad: a.ad === true, server: server,\n            befunde: befunde, gruppen: gruppen, dauer: zahl(a.dauer_ms), limitRest: zahl(a.limit_rest)\n        };\n    }<\/p>\n<p>    function skriptLaden() {\n        return new Promise(function (auf) {\n            if (window.grecaptcha) { auf(true); return; }\n            var s = document.createElement('script');\n            s.src = 'https:\/\/www.google.com\/recaptcha\/api.js?render=' + SITEKEY;\n            s.onload = function () { auf(true); }; s.onerror = function () { auf(false); };\n            document.head.appendChild(s);\n            setTimeout(function () { auf(!!window.grecaptcha); }, 8000);\n        });\n    }\n    function tokenHolen() {\n        return skriptLaden().then(function (da) {\n            if (!da || !window.grecaptcha || !window.grecaptcha.ready) { return null; }\n            return new Promise(function (auf) {\n                var fertig = false;\n                function einmal(w) { if (!fertig) { fertig = true; auf(w); } }\n                setTimeout(function () { einmal(null); }, 12000);\n                try {\n                    window.grecaptcha.ready(function () {\n                        if (fertig) { return; }\n                        if (!window.grecaptcha.execute) { einmal(null); return; }\n                        window.grecaptcha.execute(SITEKEY, { action: 'dnszone' }).then(function (t) { einmal(t || null); }, function () { einmal(null); });\n                    });\n                } catch (e) { einmal(null); }\n            });\n        }, function () { return null; });\n    }\n    function abfragen(domain) {\n        return tokenHolen().then(function (token) {\n            return fetch(ENDPUNKT, { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ domain: domain, token: token || '' }) })\n                .then(function (r) { return r.json().then(function (j) { return j; }, function () { return { fehler: 'antwort' }; }); }, function () { return { fehler: 'netz' }; });\n        });\n    }<\/p>\n<p>    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.DNSZONE = { bewerten: bewerten, darstellen: null, text: text, ENDPUNKT: ENDPUNKT, STUFEN: STUFEN, T: T };<\/p>\n<p>    var btn = document.getElementById('dnszone-btn');\n    var out = document.getElementById('dnszone-ausgabe');\n    if (!btn || !out) { return; }<\/p>\n<p>    function el(tag, stil, txt) { var e = document.createElement(tag); if (stil) { e.setAttribute('style', stil); } if (txt !== undefined && txt !== null) { e.textContent = txt; } return e; }\n    function wert(id) { var e = document.getElementById(id); return e ? e.value : ''; }\n    var UEBERSCHRIFT = 'font-family: \"Nunito Sans\", sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; margin: 22px 0 8px;';\n    var ZELLE = 'padding: 5px 12px 5px 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem;';\n    var ZELLE_WERT = 'padding: 5px 12px 5px 0; color: var(--text-primary, #e8e8ee); font-size: 0.87rem; font-family: monospace; word-break: break-all;';\n    var KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 8px; padding: 14px 16px; margin: 0 0 10px;';\n    var GUT = ' color: #7ee787;', WARN = ' color: #ffa94d;', ROT = ' color: #ff7b72;', GRAU = ' color: #8a8a99;';\n    var FARBEN = { hoch: '#ff7b72', mittel: '#ffa94d', niedrig: '#e3b341', info: '#8a8a99', gut: '#7ee787' };\n    var URTEIL = { gut: GUT, warnung: WARN, kritisch: ROT };\n    function gitter(sp) { return el('div', 'display: grid; grid-template-columns: ' + sp + '; gap: 0 18px; align-items: baseline;'); }\n    function paar(g, n, w, stil) { g.appendChild(el('div', ZELLE, n)); g.appendChild(el('div', ZELLE_WERT + (stil || ''), w)); }<\/p>\n<p>    function tabelle(b) {\n        var huelle = el('div', 'overflow-x: auto; margin: 0 0 6px;');\n        var t = el('table', 'border-collapse: collapse; width: 100%; min-width: 640px; font-size: 0.84rem;');\n        var kopf = el('tr', '');\n        [T.sp_ns, T.sp_ip, T.sp_erreichbar, T.sp_autoritaet, T.sp_serial, T.sp_a].forEach(function (n) {\n            kopf.appendChild(el('th', 'text-align: left; padding: 6px 12px 6px 0; color: #8a8a99; font-weight: 700; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.4px; border-bottom: 1px solid var(--border, #2a2a35); white-space: nowrap;', n));\n        });\n        t.appendChild(kopf);\n        var serials = {};\n        b.server.forEach(function (z) { if (z.serial !== null) { serials[z.serial] = true; } });\n        var drift = Object.keys(serials).length > 1;\n        b.server.forEach(function (z) {\n            var r = el('tr', '');\n            function zelle(txt, stil) { r.appendChild(el('td', 'padding: 7px 12px 7px 0; border-bottom: 1px solid var(--border, #2a2a35); font-family: monospace; color: var(--text-primary, #e8e8ee);' + (stil || ''), txt)); }\n            zelle(z.name, ' word-break: break-all;');\n            zelle(z.ip || '-', GRAU);\n            zelle(z.erreichbar ? T.wert_ja : T.wert_nein, z.erreichbar ? GUT : ROT);\n            zelle(z.aa ? T.wert_ja : T.wert_nein, z.aa ? GUT : WARN);\n            zelle(z.serial !== null ? String(z.serial) : '-', drift ? ROT : GRAU);\n            zelle(z.a || '-', GRAU);\n            t.appendChild(r);\n        });\n        huelle.appendChild(t);\n        return huelle;\n    }<\/p>\n<p>    function darstellen(b, ziel) {\n        ziel.innerHTML = '';\n        if (b.fehler) {\n            var txt = T['fehler_' + b.fehler] || T.fehler_unbekannt;\n            if (b.grund && T['grund_' + b.grund]) { txt = txt + ' ' + T['grund_' + b.grund]; }\n            if (b.limit !== null) { txt = txt.replace('{limit}', String(b.limit)); }\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', txt));\n            return;\n        }\n        ziel.appendChild(el('div', 'font-size: 1.05rem; font-weight: 700; margin: 0 0 12px;' + URTEIL[b.urteil], T['urteil_' + b.urteil]));<\/p>\n<p>        var g = gitter('auto auto');\n        paar(g, T.zeile_domain, b.domain, GRAU);\n        paar(g, T.zeile_ns, b.ns.length ? b.ns.join(', ') : '-', GRAU);\n        paar(g, T.zeile_a, b.adressen.length ? b.adressen.join(', ') : '-', b.adressen.length ? GRAU : WARN);\n        paar(g, T.zeile_aaaa, b.aaaa.length ? b.aaaa.join(', ') : T.wert_keine, b.aaaa.length ? GUT : GRAU);\n        paar(g, T.zeile_dnssec, b.dnssec ? (b.ad ? T.wert_dnssec_validiert : T.wert_dnssec_ohne) : T.wert_nein, b.dnssec ? GUT : GRAU);\n        if (b.dauer !== null) { paar(g, T.zeile_dauer, b.dauer + ' ms', GRAU); }\n        if (b.limitRest !== null) { paar(g, T.zeile_limit, String(b.limitRest), GRAU); }\n        ziel.appendChild(g);<\/p>\n<p>        if (b.server.length) {\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_server));\n            ziel.appendChild(tabelle(b));\n            ziel.appendChild(el('p', ZELLE + ' margin: 0 0 6px; font-size: 0.8rem;', T.tabelle_hinweis));\n        }<\/p>\n<p>        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n        var irgendwas = false;\n        STUFEN.forEach(function (s) {\n            var gr = b.gruppen[s];\n            if (!gr.length) { return; }\n            irgendwas = true;\n            ziel.appendChild(el('div', 'font-weight: 700; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.5px; margin: 14px 0 6px; color: ' + FARBEN[s] + ';', T['stufe_' + s] + ' (' + gr.length + ')'));\n            gr.forEach(function (f) {\n                var k = el('div', KASTEN + ' border-left: 3px solid ' + FARBEN[s] + ';');\n                var t = text('befund_' + f.key, f.daten) || f.key;\n                var teile = t.split(' || ');\n                k.appendChild(el('div', 'color: var(--text-primary, #e8e8ee); font-size: 0.9rem; font-weight: 700;', teile[0]));\n                if (teile[1]) { k.appendChild(el('div', ZELLE + ' padding: 6px 0 0; line-height: 1.55;', teile[1])); }\n                ziel.appendChild(k);\n            });\n        });\n        if (!irgendwas) { ziel.appendChild(el('p', ZELLE + ' margin: 0;', T.keine_befunde)); }\n    }\n    window.LW_TEST.DNSZONE.darstellen = darstellen;<\/p>\n<p>    var laeuft = false;\n    btn.addEventListener('click', function () {\n        if (laeuft) { return; }\n        laeuft = true; btn.disabled = true;\n        out.innerHTML = '';\n        out.appendChild(el('p', ZELLE + GRAU + ' margin: 0;', T.laeuft));\n        abfragen(wert('dnszone-domain')).then(function (a) { darstellen(bewerten(a), out); laeuft = false; btn.disabled = false; },\n            function () { darstellen(bewerten({ fehler: 'netz' }), out); laeuft = false; btn.disabled = false; });\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Asks a public resolver for the delegation and then queries each authoritative nameserver directly. Only the second step reveals the failures a normal lookup never shows: one server holding an older copy of the zone, one still listed but no longer answering for it, or all of them sitting in the same network.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[92769,91094,92757],"class_list":["post-15707","page","type-page","status-publish","hentry","tag-it-networks","tag-seo","tag-web-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>DNS Delegation, Serial &amp; TTL Auditor: asking every nameserver separately | Lukas Wojcik<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DNS Delegation, Serial &amp; TTL Auditor: asking every nameserver separately | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Asks a public resolver for the delegation and then queries each authoritative nameserver directly. Only the second step reveals the failures a normal lookup never shows: one server holding an older copy of the zone, one still listed but no longer answering for it, or all of them sitting in the same network.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-17T18:56:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/dns-delegation-serial-ttl-auditor\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/dns-delegation-serial-ttl-auditor\\\/\",\"name\":\"DNS Delegation, Serial & TTL Auditor: asking every nameserver separately | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-09-05T23:21:46+00:00\",\"dateModified\":\"2026-09-17T18:56:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/dns-delegation-serial-ttl-auditor\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/dns-delegation-serial-ttl-auditor\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/dns-delegation-serial-ttl-auditor\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"DNS Delegation, Serial &#038; TTL Auditor: asking every nameserver separately\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"DNS Delegation, Serial & TTL Auditor: asking every nameserver separately | Lukas Wojcik","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/","og_locale":"en_US","og_type":"article","og_title":"DNS Delegation, Serial & TTL Auditor: asking every nameserver separately | Lukas Wojcik","og_description":"Asks a public resolver for the delegation and then queries each authoritative nameserver directly. Only the second step reveals the failures a normal lookup never shows: one server holding an older copy of the zone, one still listed but no longer answering for it, or all of them sitting in the same network.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-09-17T18:56:55+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/","name":"DNS Delegation, Serial & TTL Auditor: asking every nameserver separately | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-09-05T23:21:46+00:00","dateModified":"2026-09-17T18:56:55+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/dns-delegation-serial-ttl-auditor\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/"},{"@type":"ListItem","position":3,"name":"DNS Delegation, Serial &#038; TTL Auditor: asking every nameserver separately"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15707","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=15707"}],"version-history":[{"count":4,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15707\/revisions"}],"predecessor-version":[{"id":19942,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15707\/revisions\/19942"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=15707"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=15707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}