is it DNS? wiki/Troubleshooting/Why does dig say connection timed out?
Troubleshooting

❓ Why does dig say connection timed out?

timeout
nothing answered at all
means
dig asked, nothing came back
3 tries, 5 seconds each
not
"the server said no"
(that one is REFUSED)
which
find the first silent leg
run
dig @RESOLVER NAME TYPE
then
same again with +tcp
exit
status 9, no reply
wire
UDP 53 then TCP 53 (RFC 7766)

Step 1: Read what dig did#

side I am asking

Read the message and the exit status before changing anything.

dig +timeout=2 +tries=1 @192.0.2.1 example.com A; echo $?
;; communications error to 192.0.2.1#53: timed out

; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> +timeout=2 +tries=1 @192.0.2.1 example.com A
; (1 server found)
;; global options: +cmd
;; no servers could be reached
9

One communications error line per attempt, then the summary. The default is three tries at five seconds each, so a silent server costs fifteen seconds; +tries=1 +timeout=2 cuts it to two (dig(1)). Exit 9 is "No reply from server" on the same page. NXDOMAIN and SERVFAIL both exit 0.

192.0.2.1 hosts no nameserver: 192.0.2.0/24 is reserved for documentation (RFC 5737). The timeout is the right result, which makes this the control. An answer means something local is answering for every server you name, and nothing below holds. The interception check.

Name the server on every command below. dig reads /etc/resolv.conf on every run, and with no @ it takes its servers from there. What it takes from options depends on the build, with or without @: BIND 9.17.18 and later honour timeout: and attempts: when the command line gives neither (dighost.c), 9.16 and older read ndots: alone and keep the defaults above (the same file at 9.16.50). Measured on a silent server, dig 9.20.29, 2026-09-20: timeout:1 attempts:1 finished in 1 second, timeout:9 attempts:9 in 81. macOS ships 9.10, so run dig -v first.

Asks a resolver by address for a name that does answer, from the box that is timing out.

 dig @1.1.1.1 example.com A
; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> @1.1.1.1 example.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 27089
;; 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.
; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.com. IN
AYou asked for the IPv4 address this name points at.
;; ANSWER SECTION:
example.com.
286How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
IN A 172.66.147.243
example.com. 286 IN A 104.20.23.154
;;
Query timeHow long this one lookup took, start to finish.
: 14 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
;; WHEN: Sun Sep 20 17:51:04 UTC 2026
;; MSG SIZE rcvd: 72

GO NOERROR and an answer, so this box gets a query out to port 53 and dig is not the thing that is broken

NO GO this times out too, so nothing this box asks is getting out

DO you: Read step 3 for this leg

run this query in the dig tool →

The id, the Query time, the WHEN line and a cached TTL move between runs.

Step 2: Ask each leg and find the first one that is silent#

Ask each leg by address, in the order the query travels, and stop at the first silence.

Asks a resolver you do not run, same name, same type.

 dig @9.9.9.9 example.com A
; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> @9.9.9.9 example.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 62799
;; 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: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.com. IN
AYou asked for the IPv4 address this name points at.
;; ANSWER SECTION:
example.com.
265How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
IN A 172.66.147.243
example.com. 265 IN A 104.20.23.154
;;
Query timeHow long this one lookup took, start to finish.
: 82 msec
;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
;; WHEN: Sun Sep 20 17:51:04 UTC 2026
;; MSG SIZE rcvd: 72

GO an answer here while my own resolver is silent, so it stops at mine

DO you: Open check-a-resolver

NO GO both silent from this box, so it is not one resolver

DO you: Read step 3 for this leg

run this query in the dig tool →

check-a-resolver, then check-a-forwarder if that resolver forwards.

side I run the resolver

Asks the server I run from the box it runs on, which takes the network out of the question.

 dig +timeout=2 +tries=1 @127.0.0.1 example.test SOA
; <<>> DiG 9.20.29-1~deb13u1-Debian <<>> +timeout=2 +tries=1 @127.0.0.1 example.test SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 16271
;; flags:
qrThis message is the answer coming back, not the question going out.
aaThis server says it is the authority for this name, not a cache holding a copy.
rdYou asked this server to go and find the answer for you.
; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 0b155619863d1353010000006ab01d2a96677a01c432d036 (good)
;; QUESTION SECTION:
;example.test. IN
SOAYou asked for the record at the top of the zone, the one that carries its timers.
;; ANSWER SECTION:
example.test.
3600How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
IN SOA ns.example.test. hostmaster.example.test. 1 900 180 604800 3600
;;
Query timeHow long this one lookup took, start to finish.
: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sun Sep 20 17:51:38 UTC 2026
;; MSG SIZE rcvd: 119

GO an answer on its own loopback while clients time out, so the server is up and the path to it is not

DO resolver operator: Check UDP 53 and TCP 53 into this box

NO GO silent on its own loopback, so the server is refusing to answer itself

DO resolver operator: Read the ACLs in step 3

side I run the zone

Asks a TLD server which nameservers the parent delegates this zone to.

 dig -4 +norecurse @a.gtld-servers.net example.com NS
; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> -4 +norecurse @a.gtld-servers.net example.com NS
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 53922
;; flags:
qrThis message is the answer coming back, not the question going out.
; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 13
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com. IN
NSYou asked which servers are in charge of this zone.
;; AUTHORITY SECTION:
example.com. 172800 IN NS hera.ns.cloudflare.com.
example.com. 172800 IN NS elliott.ns.cloudflare.com.
;; ADDITIONAL SECTION:
hera.ns.cloudflare.com. 172800 IN A 108.162.192.162
hera.ns.cloudflare.com. 172800 IN A 172.64.32.162
hera.ns.cloudflare.com. 172800 IN A 173.245.58.162
hera.ns.cloudflare.com. 172800 IN AAAA 2606:4700:50::adf5:3aa2
hera.ns.cloudflare.com. 172800 IN AAAA 2803:f800:50::6ca2:c0a2
hera.ns.cloudflare.com. 172800 IN AAAA 2a06:98c1:50::ac40:20a2
elliott.ns.cloudflare.com. 172800 IN A 108.162.195.228
elliott.ns.cloudflare.com. 172800 IN A 162.159.44.228
elliott.ns.cloudflare.com. 172800 IN A 172.64.35.228
elliott.ns.cloudflare.com. 172800 IN AAAA 2606:4700:58::a29f:2ce4
elliott.ns.cloudflare.com. 172800 IN AAAA 2803:f800:50::6ca2:c3e4
elliott.ns.cloudflare.com. 172800 IN AAAA 2a06:98c1:50::ac40:23e4
;;
Query timeHow long this one lookup took, start to finish.
: 96 msec
;; SERVER: 192.5.6.30#53(a.gtld-servers.net) (UDP)
;; WHEN: Sun Sep 20 17:51:04 UTC 2026
;; MSG SIZE rcvd: 359

GO a referral, no aa and no ra, with the NS set and their addresses to dig next

NO GO the TLD server is silent, which is not this zone's problem

DO you: Ask a different server in that TLD's NS set

Then ask each address in that set, recursion off.

side I run the zone

Asks one of the zone's own nameservers, recursion off, for the zone's SOA.

 dig -4 +norecurse @hera.ns.cloudflare.com example.com SOA
; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> -4 +norecurse @hera.ns.cloudflare.com example.com SOA
; (3 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 9184
;; flags:
qrThis message is the answer coming back, not the question going out.
aaThis server says it is the authority for this name, not a cache holding a copy.
; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.com. IN
SOAYou asked for the record at the top of the zone, the one that carries its timers.
;; ANSWER SECTION:
example.com.
1800How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
IN SOA elliott.ns.cloudflare.com. dns.cloudflare.com. 2415219870 10000 2400 604800 1800
;;
Query timeHow long this one lookup took, start to finish.
: 14 msec
;; SERVER: 173.245.58.162#53(hera.ns.cloudflare.com) (UDP)
;; WHEN: Sun Sep 20 17:51:21 UTC 2026
;; MSG SIZE rcvd: 102

GO aa set and the SOA, so this server is serving the zone

NO GO one address silent and the rest answering, so the failure follows whichever one the resolver picked

DO zone owner: Check that server, then the NS set at the parent

A name resolves to more than one address, so -4 or -6 pins the family. The ;; SERVER: line names the address that answered. No terminal: ask for the same NS set in the dig tool.

Causes below, in the order the query travels.

LegWho runs itThe check that separates itGO and NO GOThe move
the client config names no server, or a dead onemethe same query with @ and an addressGO: it answers, so the config was the only thing wrong. NO GO: silent by address tooyou: Read the resolv.conf line in step 1
my resolver is silentmy resolvera resolver I do not run, same nameGO: the other one answers. NO GO: both silentyou: Open check-a-resolver
the forwarder is silent and nothing falls backmy resolver, forwardingthe forwarder, asked directlyGO: it answers. NO GO: it does not, and forward only leaves the resolver no other path (BIND 9 ARM)resolver operator: Fix the forwarder, or drop the only keyword
the parent's servers are silentthe TLD operatora TLD server, +norecurseGO: a referral with the NS set. NO GO: nothing from any address in that TLD's NS setyou: Check a second TLD server before blaming the zone
the delegation names an address that is gonethe parent, and the servers it nameseach NS address, +norecurseGO: aa from each. NO GO: some answer and some are silentzone owner: Compare the parent NS set with the child's
the zone's servers are all silentthe zoneevery NS address, +norecurseGO: one of them answers. NO GO: none do, so the zone is off the airzone owner: Check every nameserver in the NS set

Step 3: Check the one leg that is silent#

Check that one address, and nothing else on the network.

Three of dig's four non-answers brought no DNS message back. Only the fourth is a server talking.

What dig printedWhat was at that address
timed outnothing came back: the packet or the reply was dropped, on the box or on the way
connection refusedthe port is closed: a TCP reset (RFC 9293 section 3.10.7.1) or ICMP port unreachable over UDP (RFC 792), which UDP "MUST pass to the application layer" (RFC 1122 section 4.1.3.3)
network unreachableno route: this box sent nothing (the capture below), or a router returned ICMP net unreachable (RFC 792). No DNS message came back
REFUSED in a headera nameserver answered and said no (RFC 1035 section 4.1.1)

The three non-answers, from a throwaway container:

$ dig +timeout=2 +tries=1 @127.0.0.1 example.test SOA
;; communications error to 127.0.0.1#53: timed out

; <<>> DiG 9.20.29-1~deb13u1-Debian <<>> +timeout=2 +tries=1 @127.0.0.1 example.test SOA
; (1 server found)
;; global options: +cmd
;; no servers could be reached

$ dig +timeout=2 +tries=1 @127.0.0.1 example.test SOA
;; communications error to 127.0.0.1#53: connection refused

; <<>> DiG 9.20.29-1~deb13u1-Debian <<>> +timeout=2 +tries=1 @127.0.0.1 example.test SOA
; (1 server found)
;; global options: +cmd
;; no servers could be reached

$ dig +tcp +timeout=2 +tries=1 @198.51.100.1 example.test SOA
;; Connection to 198.51.100.1#53(198.51.100.1) for example.test failed: network unreachable.
;; no servers could be reached

The first two are one command against one address: named running with blackhole { 127.0.0.1; }, then named stopped. They print different errors, which is the point. A server dropping this client looks like a packet filter dropping on the path, never like a closed port, because a closed port answers. The third address has no route at all.

Run both transports before calling a port shut. A server that answers over UDP and is silent over TCP is a real failure and I have no public capture of one: ten public resolver addresses checked from a clean vantage on 2026-09-20 answered over both. Reproduce it on a server you run with +tcp, then +notcp.

side I run the resolver

Asks a server whose ACL refuses this client, so the refusal arrives as an answer rather than as silence.

 dig +timeout=2 +tries=1 @127.0.0.1 example.test SOA
; <<>> DiG 9.20.29-1~deb13u1-Debian <<>> +timeout=2 +tries=1 @127.0.0.1 example.test SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
REFUSEDThis server will not answer that question for you.
, id: 51618
;; 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.
; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 233579f1ac440a98010000006ab01c372dcbcbe3d46700f2 (good)
; EDE: 18 (Prohibited)
; EDE: 20 (Not Authoritative): (recursion disabled)
;; QUESTION SECTION:
;example.test. IN
SOAYou asked for the record at the top of the zone, the one that carries its timers.
;;
Query timeHow long this one lookup took, start to finish.
: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sun Sep 20 17:47:35 UTC 2026
;; MSG SIZE rcvd: 99

GO REFUSED and EDE 18, which is the server talking: it is up, the port is open, and the ACL is the answer

NO GO silence from the same server, so it is dropping rather than refusing

DO resolver operator: Read blackhole beside allow-query

Two BIND settings. allow-query refuses, so the client gets REFUSED; blackhole ignores the address, so the client gets the timeout above (BIND 9 ARM). Rate limiting is the third: with slip 0 an over-limit reply is dropped rather than sent truncated, and only the server's own counter names it.

$ rndc stats && grep -i "rate limit" /var/cache/bind/named.stats
                  12 responses dropped for rate limits

That one is intermittent by design, so it reads as a flapping server rather than a dead one.

Last, answer size. A big signed answer does not fit one UDP datagram, so the path has to carry a bigger one or carry TCP.

Asks for an answer too big for one UDP datagram, so the reply has to come back over TCP.

 dig -4 +dnssec +bufsize=1232 +nocrypto +norecurse @a0.org.afilias-nst.info org DNSKEY
;; Truncated, retrying in TCP mode.
; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> -4 +dnssec +bufsize=1232 +nocrypto +norecurse @a0.org.afilias-nst.info org DNSKEY
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 12861
;; flags:
qrThis message is the answer coming back, not the question going out.
aaThis server says it is the authority for this name, not a cache holding a copy.
; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;org. IN
DNSKEYYou asked for the public keys this zone signs with.
;; ANSWER SECTION:
org.
3600How 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 8 [key id = 25488]
org. 3600 IN DNSKEY 256 3 8 [key id = 11859]
org. 3600 IN DNSKEY 257 3 8 [key id = 725]
org. 3600 IN DNSKEY 256 3 8 [key id = 24060]
org. 3600 IN DNSKEY 257 3 8 [key id = 26974]
org. 3600 IN RRSIG DNSKEY 8 1 3600 20261009184307 20260918174307 26974 org. [omitted]
;;
Query timeHow long this one lookup took, start to finish.
: 131 msec
;; SERVER: 199.19.56.1#53(a0.org.afilias-nst.info) (TCP)
;; WHEN: Sun Sep 20 17:57:47 UTC 2026
;; MSG SIZE rcvd: 1319

GO the retry line, then the answer with (TCP) on the SERVER line, so port 53 is open on both transports

NO GO the retry times out while small queries on the same address answer

DO you: Check TCP 53 and a 1232-byte UDP reply on that address

+nocrypto omits the key material and changes nothing on the wire; the reply is still 1319 bytes. RFC 1035 section 4.2.1 sets TC when a reply does not fit, and RFC 7766 section 1 makes TCP mandatory rather than a fallback, so a resolver does what dig just did. The client's UDP size rides in the OPT record's CLASS field (RFC 6891 section 6.1.2), and a client behind something that blocks fragments "SHOULD NOT choose a value that will cause fragmentation" (RFC 6891 section 6.2.3); DNS Flag Day 2020 put it at 1232. +bufsize=4096 was truncated on that server the same day, because it caps its own UDP at 1232 whatever the client asks. A path that eats fragments, or shuts TCP 53, breaks the big answers only.

side I am asking

One anycast address is many servers, so silence from this seat can be one instance. +nsid asks the server to name itself, where the operator publishes a name (RFC 5001).

side I am asking

Asks which instance behind an anycast address answered.

 dig +nsid @9.9.9.9 example.com A
; <<>> DiG 9.18.39-0ubuntu0.22.04.6-Ubuntu <<>> +nsid @9.9.9.9 example.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status:
NOERRORThe server had no complaint about the question.
, id: 30666
;; 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: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; NSID: 72 65 73 37 30 30 2e 71 6c 61 78 31 ("res700.qlax1")
;; QUESTION SECTION:
;example.com. IN
AYou asked for the IPv4 address this name points at.
;; ANSWER SECTION:
example.com.
295How many seconds this answer can be reused before asking again. From a cache it is the time left, so it counts down.
IN A 104.20.23.154
example.com. 295 IN A 172.66.147.243
;;
Query timeHow long this one lookup took, start to finish.
: 36 msec
;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
;; WHEN: Sun Sep 20 17:45:58 UTC 2026
;; MSG SIZE rcvd: 88

GO an NSID string, so the instance answering this seat is named and quotable in a ticket

NO GO no NSID line, so this address publishes none

DO you: Send the SERVER line and the time from a second vantage instead

See also#