is it DNS? wiki/Tools/The DNSSEC chain visualizer
Tools

The DNSSEC chain visualizer

This page is the reference manual for the chain visualizer at isitdns.net/dnssec-viz: what the walk queries, what every box and edge means, and where the page's proof honestly stops. For the one-line version of the same walk, see tldr-dnssec. For how the trust chain works in the first place, see dnssec.

Type a domain and your browser walks its real DNSSEC chain of trust, root to answer, then draws it as a graph: one column per zone, a box per key, DS, and signature, edges colored by what the page could verify. Every value was fetched by your browser seconds ago. Nothing is canned, and when the walk fails, nothing is drawn rather than drawing stale data.

Asks for the keys the visualiser draws the chain from.

 dig @1.1.1.1 isitdns.net DNSKEY +dnssec
; <<>> DiG 9.20.11-0ubuntu0.2-Ubuntu <<>> @1.1.1.1 isitdns.net DNSKEY +dnssec
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 51699
;; flags:
qrThis message is the answer coming back, not the question going out.
rdYou asked this server to go and find the answer for you.
raThis server says it is willing to go and find answers for you.
adThis server says it checked the signatures, and they held up.
; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;isitdns.net. IN
DNSKEYYou asked for the public keys this zone signs with.
;; ANSWER SECTION:
isitdns.net.
1088How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
IN DNSKEY 256 3 13 oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar0IRd8 KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==
isitdns.net. 1088 IN DNSKEY 257 3 13 mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+ KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==
isitdns.net. 1088 IN RRSIG DNSKEY 13 2 3600 20261028172448 20260828172448 2371 isitdns.net. dtPWRV1FNeaOSdirI52faTzB7rskfmfA5VH3JSjB3KYfFmHtUxAAFyW6 NwAsS4hApjUKD29/lDWjaCk5XVeL8w==
;;
Query timeHow long this one lookup took, start to finish.
: 32 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
;; WHEN: Mon Sep 14 17:42:31 CDT 2026
;; MSG SIZE rcvd: 307

good: NOERROR, the DNSKEY set, and an RRSIG over it

bad: SERVFAIL, which means the chain is broken above this zone

The vantage#

The queries run from your browser, over DNS-over-HTTPS to cloudflare-dns.com (1.1.1.1), using Cloudflare's JSON API with the DO bit set (do=1, the EDNS0 flag that asks for DNSSEC records, RFC 6891). That JSON format is a Cloudflare and Google extension, not RFC 8484: RFC 8484 defines DoH carrying application/dns-message, the wire format. The page states the vantage above the graph.

That vantage is a feature. DoH rides port 443, so a router that intercepts port 53 cannot answer in Cloudflare's place; the chain you see is the chain 1.1.1.1 sees. It is still one vantage: a zone mid-rollover can legitimately show a different chain from a different resolver at the same moment.

What the walk does#

Who we ask (the zone queries fire in parallel; only the leaf waits for them):

  1. For every zone cut from the root down (., then each suffix of the name, per the zone-cut terminology in RFC 9499): the zone's DNSKEY RRset.
  2. For every cut below the root: the child's DS RRset, which lives in the parent zone (RFC 4034 section 5).
  3. The leaf answer: the domain's A RRset, falling back to AAAA when no A exists, with the covering RRSIGs (RFC 4034 section 3).

For a two-cut name like isitdns.net that is six DoH queries; the status line under the form reports the honest count and total time for every run. The walk depth caps at ten labels, so absurdly deep names walk the top ten cuts and still fetch the leaf.

When a query returns SERVFAIL, the page refetches it with CD=1 (Checking Disabled, RFC 4035 section 3.2.2), so a validation-broken chain still yields the records that break it. The retry is flagged on the column (SERVFAIL, refetched with CD=1) and in the verdict; it is never passed off as a validated answer. The SERVFAIL that triggered the retry usually carried an Extended DNS Error naming the resolver's own reason, which this page does not draw; extended-dns-errors is how to read it.

What comes back is then checked client-side:

  • Key tags are computed from each DNSKEY's rdata per RFC 4034 appendix B, not trusted from the DS side. When a tag cannot be computed the box says (tag not computed) and names why; it is never faked.
  • DS digests are recomputed with WebCrypto: hash the owner name in wire form plus the DNSKEY rdata (SHA-1, SHA-256, or SHA-384, whichever the DS names) and compare byte for byte against the digest the parent published. A match is the strongest thing this page proves.
  • RRSIG validity windows (inception and expiration, RFC 4034 section 3.1.5) are checked against your clock, and the tooltip shows both timestamps with relative time.

Reading the graph#

Columns are zones, left to right from the root: . (root), the TLD, the zone, then a final column headed the answer. Each column's subhead reports what came back: the key count plus AD=1 when the resolver validated, or the CD-retry flag.

Boxes are the records:

BoxWhat it is
DNSKEY <tag>A zone key, labeled KSK or ZSK by its flags field, with the algorithm. KSK boxes get an accent border. The root KSK carries a TRUST ANCHOR badge; see the boundary section for why.
DS <tag>The parent's fingerprint of the child's KSK. Drawn in the parent's column, because that is where DS records live.
RRSIG <type>The signature over the final RRset, in the answer column.
<type> RRsetThe answer itself: the records, TTL, rcode, and the resolver's AD flag.
no DNSKEY / no DS for <zone>Note boxes for the absences: an unsigned zone, or an unsigned delegation. When the parent's negative answer carried an NSEC/NSEC3 denial proof, the tooltip says so.

Edges are the relations, and the color is the verdict:

EdgeMeans
Solid limeVerified relation: a DS digest recomputed here and matched, a signing key tag computed here and matched, an RRSIG window valid on your clock.
Dashed amberNot verifiable from client data: the relation rests on signature bytes this page does not verify, a digest type WebCrypto cannot compute, or a tag that could not be computed.
Solid redMismatch or out of validity: a DS digest that recomputed differently, a DS whose tag matches no live key, an expired or not-yet-valid RRSIG.

Hover or tap any box or edge for the evidence: the raw field values, and a PASS / FAIL / NOTE line for each check the page ran on it. Click to pin the tooltip.

Below the graph, How we walked it lists every step in order: who we asked, what came back, per zone. The verdict renders last, after the evidence.

The verdicts#

One line, derived from the walked chain on every run:

VerdictWhen
CHAIN INTACT (lime)Every DS digest the page could recompute matched, every signature window is current, and the resolver set AD=1 on the answer. If any DS used a digest type the browser cannot recompute, the line says how many.
UNSIGNED PATH (amber)A cut in the path has no DS: an unsigned delegation. The verdict adds "That is not an error, it is just not DNSSEC."
SIGNED, BUT (amber)The chain drawn checks out client-side, but the resolver did not set AD on the final answer.
NXDOMAIN (amber)The name does not exist. Named as what it is, never folded into unsigned; the chain drawn is the path that would sign it, and the denial itself can be DNSSEC-proven (NSEC/NSEC3).
BROKEN (red)Something failed: a zone SERVFAILed under validation, a DS matches no live key or recomputed to a different digest, or the RRSIG over the answer is outside its window. Each break is named.

Three worked states#

Live deep links; the page accepts ?d=<domain> and runs the walk on load.

Intact: isitdns.net. We ask for DNSKEYs at the root, net, and isitdns.net, DS at the two cuts, then the A answer. Everything comes back: both DS digests recompute and match, the RRSIG window is current, the resolver sets AD=1. Every trust edge is solid lime. Verdict: CHAIN INTACT.

Unsigned: github.com. The root and com columns fill in normally, then com publishes no DS for github.com and the zone publishes no DNSKEY. The delegation edge draws dashed amber with a no DS note box, and the answer arrives with no RRSIG. Verdict: UNSIGNED PATH. Nothing is broken; there is simply nothing to verify below com.

Broken: dnssec-failed.org. This zone is deliberately signed wrong: the DS at org fingerprints a key the zone does not serve. The first queries SERVFAIL, the page refetches with CD=1 and flags it, and the DS-to-key edge comes up solid red because no live DNSKEY carries the DS's tag. Verdict: BROKEN, naming the SERVFAIL and the orphaned DS. Cloudflare's own reason for that SERVFAIL is EDE 9, DNSKEY Missing, which is the same break stated in one line instead of drawn (extended-dns-errors). dnssec-troubleshooting is the field guide for chains that look like this one.

The same walk from your terminal#

Every section of the graph has a one-line dig equivalent. The DoH vantage note applies in reverse here: these ride your local port-53 path, so behind an intercepting router they can disagree with the page, and the disagreement is the finding (when-its-dns).

The keys column for any zone:

dig @1.1.1.1 isitdns.net DNSKEY +dnssec

The DS boxes in the parent column:

dig @1.1.1.1 isitdns.net DS +dnssec

The answer column, RRset plus RRSIG, with the ad flag as the resolver's verdict:

dig @1.1.1.1 isitdns.net A +dnssec

And the whole verdict at once, validated on your own machine, which is the one thing the page cannot do for you:

delv @1.1.1.1 isitdns.net A
; fully validated

What the page verifies, and what it does not#

The graph draws its own limits, and the page states them under the graph. In full:

  • Computed in your browser: key tags from DNSKEY rdata (RFC 4034 appendix B), DS digests recomputed with WebCrypto and byte-compared against the parent's DS, and every RRSIG window checked against your clock.
  • Not computed in your browser: the signature bytes. Verifying an RRSIG needs the canonical wire form of the whole RRset (RFC 4035 section 5.3); this page does not do that math. Where a relation rests on the signature alone, the edge is dashed amber, and the resolver's AD flag (RFC 4035 section 3.2.3) is shown as the validating resolver's own verdict, clearly labeled as its verdict and not the page's.
  • The root KSK is a trust anchor, not a conclusion. A trust anchor is a key you configure rather than derive (RFC 4033 section 2). The root DNSKEY RRset is fetched live, but trust in it comes from resolver configuration; the page does not fetch the IANA trust-anchor file, so the TRUST ANCHOR badge marks an assumption, not a proof.
  • One vantage. Your browser, one DoH resolver. A different vantage can see a different chain mid-rollover.

Want the full professional graph with NSEC proofs and per-server responses? That is DNSViz, and this page links to it for exactly that reason.

See also#

  • tldr-dnssec: the same walk as one verdict line, when you do not need the drawing
  • dnssec: how the trust chain works, and the two-step signed-or-not check
  • dnssec-troubleshooting: what to do when the verdict is BROKEN
  • extended-dns-errors: the resolver's reason code for the same broken chain
  • DNSViz: the reference visualizer, with NSEC chains and per-server views
  • dig-flags: the ad, cd, and do bits this page keeps citing
  • when-its-dns: what to do when the page and your terminal disagree