# dig: DNS Query Debugging in CLI

LLMS index: [llms.txt](/en/llms.txt)

---

DNS resolvers return the wrong address, clients don't see updates, or it's unclear which server is handling requests. `dig` (Domain Information Groper) is the standard CLI tool for DNS diagnostics. Works on Linux, macOS, and Windows via WSL.

## Installation

```bash
# Debian/Ubuntu
apt install dnsutils

# RHEL/CentOS/Alma
dnf install bind-utils

# macOS — ships with the system
# Windows — via WSL or ISC official binaries
```

## Basic Flags

`dig` has two classes of options: short flags (start with `-`) control query behavior, while keywords with `+` control output format.

```bash
dig example.com
```

Without arguments the output is verbose — lots of header information. For debugging you pick the pieces you need.

| Flag | Purpose |
|------|---------|
| `-b <addr>` | Outbound IP address (multi-interface hosts) |
| `-f <file>` | Read queries from file, one per line |
| `-p <port>` | Non-standard DNS server port |
| `-t <type>` | Record type: A, AAAA, MX, TXT, SOA, NS, CNAME, ANY |
| `-c <class>` | Network class (default: IN — Internet) |
| `-x <addr>` | Reverse lookup (PTR) |
| `-6` | Force IPv6 |
| `-4` | Force IPv4 |

## Quick Response: +short

For scripts and quick checks:

```bash
dig example.com +short
# 93.184.216.34
```

```bash
dig mail.example.com +short
# 10 mailgateway.example.com.
```

If the record doesn't exist — empty output. For CNAMEs you see the final address but not the chain.

For AAAA records:

```bash
dig example.com AAAA +short
# 2606:2800:220:1::248a:2873
```

> [!NOTE]
> `+short` doesn't show TTL and doesn't guarantee it's the final answer. A CNAME loop will return the last record in the chain, not an error.

## Full Response: +noall +answer

When you need TTL, canonical name, and all records at once:

```bash
dig example.com +noall +answer
# example.com.         86400   IN      A       93.184.216.34
```

```bash
dig example.com MX +noall +answer
# example.com.         3600    IN      MX      10 mailstore1.example.com.
# example.com.         3600    IN      MX      20 mailstore2.example.com.
```

TTL in seconds. Small values (60–300) mean the record changes frequently.

Verbose response with timing:

```bash
dig example.com +stats
```

## Reverse Lookup: -x

Reverse zone: IP → hostname.

```bash
dig -x 93.184.216.34 +short
# domain.example.com.
```

```bash
dig -x 8.8.4.4 @1.1.1.1 +short
# dns.google.
```

> [!TIP]
> Not all PTR zones are populated. Empty response with `-x` is normal, especially for client addresses.

## IPv6: -6

Force IPv6 transport to the DNS server:

```bash
dig -6 @2001:4860:4860::8888 example.com AAAA +short
# 2606:2800:220:1::248a:2873
```

If you want an AAAA record over IPv4 transport — just request the type:

```bash
dig @1.1.1.1 example.com AAAA +short
```

## Chain Tracing: +trace

Shows the path from root servers to the final answer:

```bash
dig example.com +trace +noall +answer
```

Output is split into sections: `.` (root), TLD (`.com`), authoritative NS, response.

```bash
dig internal.example.com +trace +noall +answer
# .                       518400  IN      NS      a.root-servers.net.
# com.                    172800  IN      NS      a.gtld-servers.net.
# example.com.            172800  IN      NS      a.iana-servers.net.
# internal.example.com.   300     IN      A       10.0.1.50
```

`+trace` is slow — walks the hierarchy recursively. Use it for NXDOMAIN and SERVFAIL diagnosis.

## Specific Resolver: @server

By default `dig` uses the system resolver from `/etc/resolv.conf`. Specifying explicitly compares responses or bypasses local cache:

```bash
dig @8.8.8.8 example.com +short
dig @1.1.1.1 example.com +short
dig @9.9.9.9 example.com +short
```

```bash
dig @ns1.example.com example.com AXFR +short
```

AXFR transfer works only if the NS allows it.

> [!WARNING]
> Full zone AXFR is sensitive. Don't do this on third-party NS without reason.

## Common Scenarios

**Checking SOA and NS records**

```bash
dig example.com SOA +short
# ns1.example.com. admin.example.com. 2024011501 7200 3600 1209600 86400

dig example.com NS +short
# ns1.example.com.
# ns2.example.com.
```

Serial in SOA — if you updated records but it didn't increase, transfer hasn't happened.

**TTL of a specific record**

```bash
dig example.com A +noall +answer +ttlid
# example.com.         300     IN      A       93.184.216.34
```

300 seconds is low TTL, normal for frequently changing records. Static records usually sit at 3600+.

**CNAME chain**

```bash
dig www.example.com +trace +noall +answer
```

The chain displays in full. If a redirect broke somewhere — NXDOMAIN or SERVFAIL at which step becomes clear from the output.

**Comparing resolvers**

```bash
for ns in 8.8.8.8 1.1.1.1 9.9.9.9; do
  echo "=== $ns ===";
  dig @$ns example.com +short;
done
```

```bash
# Output
=== 8.8.8.8 ===
93.184.216.34
=== 1.1.1.1 ===
93.184.216.34
=== 9.9.9.9 ===
93.184.216.34
```

If addresses differ — the issue isn't on your service side, it's with that specific resolver or record propagation.

**SERVFAIL analysis**

```bash
dig @ns1.example.com _sip._tcp.example.com SRV +noall +answer +stats
```

Check flags: SERVFAIL in the response means the NS couldn't fetch data. Verify the requested record type actually exists in the zone.

**ANY query (carefully)**

```bash
dig example.com ANY +short
```

Deprecated in production. But for quick diagnostics of all record types on a new NS — it works.
