DNS usually starts ordinary lookups over UDP, but name servers also need TCP on port 53 for truncated replies, zone transfers, and larger responses. Forcing a lookup through TCP with dig separates a DNS answer problem from a transport problem when firewalls, resolvers, or authoritative servers handle UDP and TCP differently.
The +tcp option makes dig open a TCP connection to the selected resolver or authoritative server. The DNS status and answer rows are read the same way as a normal lookup, while the SERVER statistics line ends with (TCP) when the query completed over that transport.
Use an explicit @server target when the resolver path matters. A successful TCP lookup proves that the selected server answered the question over TCP from the client path that ran the command; a timeout or refused connection points to TCP/53 reachability or server policy before it says anything about the record value.
Steps to query DNS over TCP with dig:
- Choose the DNS question and server to test.
server: 1.1.1.1 name: example.com type: A
Use the same name and record type for every comparison. Change only the @server value when checking a different resolver or authoritative name server.
- Run the lookup with +tcp.
$ dig @1.1.1.1 +tcp +noall +comments +question +answer +stats example.com A ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 108 IN A 104.20.23.154 example.com. 108 IN A 172.66.147.243 ;; Query time: 6 msec ;; SERVER: 1.1.1.1#53(1.1.1.1) (TCP) ##### snipped #####
The (TCP) suffix on the SERVER line confirms that dig completed this lookup over TCP instead of UDP.
- Read the DNS status and answer count before comparing record data.
NOERROR means the server returned a DNS response for the name. ANSWER: 2 means two answer rows matched the requested A record type.
- Compare the same lookup without +tcp when a transport difference is suspected.
$ dig @1.1.1.1 +noall +comments +question +answer +stats example.com A ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 107 IN A 104.20.23.154 example.com. 107 IN A 172.66.147.243 ;; Query time: 7 msec ;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP) ##### snipped #####
Matching status and answer rows usually mean the DNS answer is not transport-specific. Different TCP and UDP results point to resolver policy, packet size, truncation, firewall, or path behavior.
- Recognize a TCP reachability failure.
$ dig @203.0.113.53 +tcp +time=1 +tries=1 example.com A ;; Connection to 203.0.113.53#53(203.0.113.53) for example.com failed: timed out. ;; no servers could be reached
203.0.113.53 is a documentation address used to show the timeout shape. Replace it with a resolver or name server that you are allowed to test.
- Record the transport result before changing DNS records.
TCP result: reached 1.1.1.1 over TCP/53 DNS status: NOERROR Answer set: 104.20.23.154, 172.66.147.243 UDP comparison: same answer set Next action: investigate TCP/53 only if the TCP lookup fails or differs
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.