{"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-06T01:21:46","modified_gmt":"2026-09-05T23:21:46","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 rate counter.<\/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 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 rate counter.\",\"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}. The servers hold different versions of the zone, so which answer a visitor gets depends on which server their resolver happens to ask. Usually a zone transfer failed or a hidden primary did not notify everyone.\",\"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 = '\/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 - Blog<\/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 - Blog\" \/>\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=\"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 - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-09-05T23:21:46+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\":\"luky\",\"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\":\"luky\"},\"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 - Blog","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 - Blog","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","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 - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-09-05T23:21:46+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":"luky","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":"luky"},"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":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15707\/revisions"}],"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}]}}