How to check DNSSEC validation with dig

DNSSEC validation can fail even when a domain still has ordinary address records. dig shows the recursive resolver response header, DNSSEC OK request bit, and signature records, so a DNS operator can tell whether a resolver authenticated a signed answer or rejected a broken chain.

Cloudflare Public DNS at 1.1.1.1 is a known validating resolver, which keeps the baseline output independent of the workstation's local resolver. Replace @1.1.1.1 with the recursive resolver under test when checking a corporate, ISP, or self-hosted validation path.

A signed domain should return NOERROR with the ad flag when the resolver validates the answer. A deliberately broken signed name should return SERVFAIL, and the same name with +cd should return data without ad when validation is the reason for the failure.

Steps to check DNSSEC validation with dig:

  1. Choose the resolver that should perform validation.

    @1.1.1.1 targets Cloudflare Public DNS. Substitute the resolver address that clients actually use when the target is an internal or managed recursive resolver.

  2. Query a signed domain with DNSSEC records requested.
    $ dig @1.1.1.1 internetsociety.org A +dnssec
    
    ; <<>> DiG 9.20.18-1ubuntu2.1-Ubuntu <<>> @1.1.1.1 internetsociety.org A +dnssec
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15123
    ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags: do; udp: 1232
    ;; QUESTION SECTION:
    ;internetsociety.org.		IN	A
    
    ;; ANSWER SECTION:
    internetsociety.org.	267	IN	A	104.18.16.166
    internetsociety.org.	267	IN	A	104.18.17.166
    internetsociety.org.	267	IN	RRSIG	A 13 2 300 20260628022255 20260626002255 34505 internetsociety.org. ##### snipped #####
    
    ;; Query time: 7 msec
    ;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)

    The ad flag is the resolver's Authenticated Data signal. The do EDNS flag shows that +dnssec requested DNSSEC records, but do alone does not prove validation.

  3. Query a deliberately broken signed name through the same resolver.
    $ dig @1.1.1.1 www.dnssec-failed.org A +dnssec
    
    ; <<>> DiG 9.20.18-1ubuntu2.1-Ubuntu <<>> @1.1.1.1 www.dnssec-failed.org A +dnssec
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 47070
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags: do; udp: 1232
    ; EDE: 9 (DNSKEY Missing): (no SEP matching the DS found for dnssec-failed.org.)
    ;; QUESTION SECTION:
    ;www.dnssec-failed.org.		IN	A
    
    ;; Query time: 7 msec
    ;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)

    SERVFAIL with DNSSEC records requested and no ad flag is the rejection signal for this resolver view. Some resolvers omit the EDE diagnostic line.

  4. Re-run the broken lookup with checking disabled for that query.
    $ dig @1.1.1.1 www.dnssec-failed.org A +dnssec +cd
    
    ; <<>> DiG 9.20.18-1ubuntu2.1-Ubuntu <<>> @1.1.1.1 www.dnssec-failed.org A +dnssec +cd
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20908
    ;; flags: qr rd ra cd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags: do; udp: 1232
    ; EDE: 9 (DNSKEY Missing): (no SEP matching the DS found for dnssec-failed.org.)
    ;; QUESTION SECTION:
    ;www.dnssec-failed.org.		IN	A
    
    ;; ANSWER SECTION:
    www.dnssec-failed.org.	267	IN	A	68.87.109.242
    www.dnssec-failed.org.	267	IN	A	69.252.193.191
    www.dnssec-failed.org.	7167	IN	RRSIG	A 13 3 7200 20260702015706 20260624225206 32784 dnssec-failed.org. ##### snipped #####
    
    ;; Query time: 8 msec
    ;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)

    +cd sets the Checking Disabled bit for this lookup request. If +cd returns address records while the normal DNSSEC query returns SERVFAIL, the failure is validation-related rather than a missing ordinary A record.