Skip to content
Commitpedia
Log in Join & edit

DNS check script: compare answers from several resolvers

A bash script that looks up one or more names against your system resolver and three public resolvers, shows each answer with its TTL and warns when they disagree or /etc/hosts overrides the name.

Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?

Edit history of DNS check script: compare answers from several resolvers: 1 recorded edit
Edit history · 1 edit
Type
Script
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Language
bash
Licence
CC0-1.0

What this changes

Read-only: it sends DNS queries with dig and reads /etc/hosts. Nothing is written or changed.

How to undo it

Nothing to undo.

After you change a DNS record, or when a site works for a colleague but not for you, the question is “who sees what?”. This script asks several resolvers the same question and lines up the answers. It only needs dig (package dnsutils on Debian and Ubuntu, bind-utils on RHEL family; preinstalled on macOS).

The script

#!/usr/bin/env bash
set -uo pipefail

RESOLVERS=${RESOLVERS:-"system 1.1.1.1 9.9.9.9 8.8.8.8"}
TYPE=${TYPE:-A}

if (( $# < 1 )); then
  echo "usage: $0 name [name ...]" >&2
  echo "  TYPE=AAAA|MX|TXT|CNAME $0 name      record type (default A)" >&2
  echo "  RESOLVERS=\"system 1.1.1.1\" $0 name  resolvers to compare" >&2
  exit 2
fi
command -v dig >/dev/null 2>&1 || { echo "dig not found (package dnsutils or bind-utils)" >&2; exit 2; }

status=0
for name in "$@"; do
  echo "== $name ($TYPE)"
  declare -A seen=()
  for r in $RESOLVERS; do
    if [[ $r == system ]]; then
      out=$(dig +short +time=3 +tries=1 "$name" "$TYPE" 2>&1)
      ttl=$(dig +noall +answer +time=3 +tries=1 "$name" "$TYPE" 2>/dev/null | awk '{print $2; exit}')
    else
      out=$(dig +short +time=3 +tries=1 "@$r" "$name" "$TYPE" 2>&1)
      ttl=$(dig +noall +answer +time=3 +tries=1 "@$r" "$name" "$TYPE" 2>/dev/null | awk '{print $2; exit}')
    fi
    if [[ -z $out ]]; then
      answer="(no answer)"
    elif [[ $out == *"connection timed out"* ]]; then
      answer="(timeout)"
    else
      answer=$(echo "$out" | sort | paste -sd ' ' -)
    fi
    seen["$answer"]=1
    printf '  %-12s %-50s ttl=%s\n' "$r" "$answer" "${ttl:--}"
  done
  if (( ${#seen[@]} > 1 )); then
    echo "  WARN: resolvers disagree (propagation in progress, split-horizon DNS or a stale cache)"
    status=1
  fi
  if grep -qE "^[^#]*[[:space:]]$name([[:space:]]|$)" /etc/hosts 2>/dev/null; then
    echo "  NOTE: /etc/hosts has an entry for $name; local programs will use it instead of DNS"
  fi
  unset seen
done
exit $status

How to use it

chmod +x dnscheck.sh
./dnscheck.sh example.com www.example.com
TYPE=MX ./dnscheck.sh example.com
RESOLVERS="system 1.1.1.1 ns1.example-dns.net" ./dnscheck.sh app.example.com
== app.example.com (A)
  system       192.0.2.10                                         ttl=287
  1.1.1.1      198.51.100.7                                       ttl=60
  9.9.9.9      198.51.100.7                                       ttl=60
  8.8.8.8      198.51.100.7                                       ttl=55
  WARN: resolvers disagree (propagation in progress, split-horizon DNS or a stale cache)

Reading the output

  • All the same: DNS is consistent; if the site still fails, the problem is the connection or the service, not the name.
  • Your system resolver differs from the public ones with a high TTL: your local resolver (router, ISP, systemd-resolved) still caches the old record. Wait for the TTL to run out, or flush it (resolvectl flush-caches on Linux with systemd-resolved, sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder on macOS).
  • Only your system resolver answers and the public ones return nothing: the name exists only on an internal DNS server (split-horizon). That is expected inside company networks and VPNs.
  • Public resolvers disagree with each other: the change is still propagating. Adding the authoritative name server to RESOLVERS shows the value that will eventually win.
  • NOTE about /etc/hosts: a line there beats every resolver for programs on this machine, which is a classic source of “it only breaks on my laptop”.

Official documentation

Did this work for you?

No votes yet. Be the first.

If it did not work, the report form below tells the editors what went wrong.

See also

  • 0266 What is a port? A port is a numbered door on a computer that lets one machine run many network services at the same time. Beginner · Explains an idea · Any system Article DNS, IP addresses & ports 15 Oct 2026
  • 0274 What is DNS? DNS is the internet's phone book: it turns names like example.com into the IP addresses computers actually use. Beginner · Explains an idea · Any system Article DNS, IP addresses & ports 15 Oct 2026
  • 0275 What is an IP address? An IP address is the unique number that identifies a device on a network so data knows where to go. Beginner · Explains an idea · Any system Article DNS, IP addresses & ports 15 Oct 2026
  • 0341 DNS, IP addresses and ports explained for beginners An IP address says which machine, a port says which program on it, and DNS turns names into addresses. The three ideas… Beginner · Explains an idea · Linux, macOS Article DNS, IP addresses & ports 15 Oct 2026
  • 0342 Which process is using a port, and how to free it Find the program behind a busy port with ss, lsof or fuser, decide whether to stop it properly or kill it, and… Beginner · Step by step · Linux, macOS Article DNS, IP addresses & ports · Networking & firewalls 15 Oct 2026
  • 0343 Fix: Connection refused and Connection timed out, what each one means Refused means the host answered and nothing is listening there. Timed out means no answer at all, usually a firewall or wrong… Beginner · Fixes an error · Linux, macOS Article DNS, IP addresses & ports · Firewalls 15 Oct 2026

Repos in the wild

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Dominik +3,976 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?