53
The name-resolution port, on UDP and TCP — and on most modern Linux desktops it is already taken by systemd-resolved, which is why your dnsmasq or Pi-hole will not start.
Run the line for your platform. Each one names the process holding the port and the address it bound to, which is usually the whole answer.
sudo lsof -nP -i :53Deliberately no `-sTCP:LISTEN` here: UDP sockets have no LISTEN state, and adding that filter would hide the half of DNS that matters most. `-i :53` selects both protocols. The NODE column is the protocol — `TCP` or `UDP` — and TYPE is only the address family (`IPv4` / `IPv6`), so two IPv4 rows can still be one of each. A `UDP` row has no state in parentheses while a `TCP` row shows `(LISTEN)`. The NAME column carries the bound address: `127.0.0.1:53` serves only this machine, `*:53` serves every interface. `-n` and `-P` keep hosts and ports numeric. Without `sudo` a root-owned resolver does not appear at all.
sudo ss -tulnp 'sport = :53'`-t` and `-u` together cover TCP and UDP, `-l` limits it to listening sockets, `-n` keeps ports numeric and `-p` names the process. The address column is the whole answer: `127.0.0.53:53` is the systemd-resolved stub and is the reason a second resolver cannot bind, `127.0.0.1:53` is a local-only resolver, and `0.0.0.0:53` or `[::]:53` is a server open to the network. UDP rows show no connection state, which is expected, not an error. Process names appear as `users:(("systemd-resolve",pid=701,fd=12))`; without `sudo` that column is blank for processes you do not own.
sudo netstat -tulnp | grep ':53 'The net-tools spelling for hosts without iproute2, with the same flag meanings. The PID/Program name column requires superuser privileges for sockets you do not own, and its man page notes the value is not trustworthy. Keep the trailing space in the pattern or `:53` will also match `:5353`, which is multicast DNS and a completely different service.
netstat -ano | findstr :53`-a` matters more than usual here: Microsoft documents it as showing "all active TCP connections and the TCP and UDP ports on which the computer is listening", so it is what surfaces the UDP side. `-n` keeps things numeric and `-o` adds the owning PID, which `tasklist /FI "PID eq 1234"` turns into a name. On a domain controller the owner is `dns.exe` and is supposed to be there. Watch the substring match: `:53` also hits `:5353` and `:53000`.
`nmap -Pn -sU -p 53 ns1.example.com` scans the UDP side, which is the side that carries real queries. `-sU` needs raw sockets, so run it under `sudo` or nmap stops with `You requested a scan type which requires root privileges.` before sending anything. Drop `-sU` to test TCP 53 instead, and test both, because a firewall that opens only one is a classic intermittent-failure generator. UDP results are less decisive than TCP: silence is indistinguishable from a drop, so nmap reports `open|filtered` rather than committing, while `closed` means an ICMP port-unreachable came back. Add `--reason` to see exactly what was observed. For a real answer, skip the scan and ask the server a question: `dig @ns1.example.com example.com A` either returns records, times out, or is refused, and that is the same information with far less ambiguity. Scan only hosts you are responsible for.
| What you see | What it means |
|---|---|
dnsmasq: failed to create listening socket for port 53: Address already in use | On a systemd distribution this is almost always the systemd-resolved stub listener already holding 127.0.0.53:53. Confirm it with the Linux probe above, then either set `DNSStubListener=no` in `/etc/systemd/resolved.conf` and restart systemd-resolved, or bind your resolver to a specific interface address instead of the wildcard. Fighting it by killing the process will just come back after reboot. |
;; communications error to 192.0.2.1#53: connection refused | The host answered, and answered no. Nothing is bound to port 53 on that address: the resolver is stopped, crashed on start, or is bound only to loopback so it is invisible from anywhere but the server itself. Run the probe on the resolver host and look at the bound address, not just at whether a process exists. |
;; connection timed out; no servers could be reached | Nothing came back at all. A packet filter is dropping the query — a security group, an on-host firewall, or a network ACL — or the address is simply wrong. Because UDP is connectionless there is no reset to tell you otherwise, so the silence lasts the full timeout. Test TCP with `dig +tcp` as well: if TCP works and UDP does not, the block is protocol-specific. |
;; Truncated, retrying in TCP mode. — then a timeout | The answer exceeded what would fit in a UDP response, the server set the TC bit as RFC 1035 requires, and the client's TCP retry was blocked. This is the failure mode of a firewall that opened UDP 53 and forgot TCP 53: small lookups succeed, large ones such as DNSSEC-signed or many-record answers fail, and the whole thing looks random until you notice which names break. |
REFUSED status in a dig answer, or ;; got answer with no records | The port, the network and the daemon are all fine — the server understood the query and declined it. Usually you asked a recursive question of an authoritative-only server, or asked from an address outside its allowed recursion list. Nothing in the network needs changing; the access policy does. |
bind: Permission denied binding port 53 as a normal user | Port 53 is below 1024 and therefore privileged, so the kernel refuses the bind with EACCES regardless of what is or is not already listening. Start the resolver through its service manager, grant `CAP_NET_BIND_SERVICE` on Linux, or test on a high port with `dig -p 5300 @127.0.0.1`. |
IANA assigns port 53 to `domain` on both TCP and UDP, and both halves are genuinely in use. UDP carries ordinary queries because a lookup is one small packet each way and setting up a connection would cost more than the answer. TCP exists for the cases UDP cannot serve: RFC 1035 states that "Messages carried by UDP are restricted to 512 bytes", and a response that does not fit is returned truncated with the TC bit set so the client repeats the query over TCP. EDNS(0) (RFC 6891) lets a client advertise a larger UDP buffer, which keeps most big answers on UDP, but RFC 7766 makes TCP support a requirement rather than an optional fallback — a resolver reachable only on UDP is broken, not merely limited. Zone transfers (AXFR) always use TCP. Encrypted DNS does not live here at all: DNS over TLS is port 853, registered as `domain-s` by RFC 7858, and DNS over HTTPS rides on 443. Multicast DNS, the `.local` name resolution used by printers and AirPlay, is port 5353 (RFC 6762), so a `5353` line in your output is not your resolver. The single most common local conflict is systemd-resolved, whose manual states that its stub listener occupies "Port 53 on IPv4 addresses 127.0.0.53 and 127.0.0.54", covering both UDP and TCP. That is why dnsmasq, Pi-hole, CoreDNS and BIND all fail to start on a stock Ubuntu box until `DNSStubListener=no` is set in `/etc/systemd/resolved.conf`. Inside Docker containers the resolver is a different address again, `127.0.0.11`.
An authoritative server has to be reachable; a recursive resolver must not be. A resolver that answers recursive queries for the whole internet is a reflection and amplification weapon: an attacker sends a small query with your victim's address spoofed as the source, and your server mails the much larger answer to the victim. RFC 5358 (BCP 140) exists specifically to tell operators not to leave recursive nameservers open, and open resolvers are located by continuous internet-wide scanning within hours of appearing. Restrict recursion to your own address ranges, and keep authoritative and recursive roles on separate servers so the authoritative one can answer the world without recursing for it. Restrict AXFR to your declared secondaries too — an unrestricted zone transfer hands an attacker your complete internal naming map, hostnames, and often the topology of your network in one request. Rate-limit responses, and remember that because UDP is connectionless, source addresses in queries are trivially forged, so any access control based on them is weaker than it looks. Do not open TCP 53 and forget it: if you allow UDP but block TCP, resolution works until an answer grows past the UDP buffer and then fails in a way that looks intermittent and random.
All of these run in your browser — nothing is uploaded.
Ports people usually end up checking in the same session as 53.
Almost always permissions. lsof and ss list the socket but hide the owning process when it belongs to another user, so a server started by a system account, by a container runtime or by launchd shows up as an anonymous listener until you re-run the command with sudo. On Windows the opposite happens: netstat shows nothing at all, yet a bind still fails, which means the port sits inside a range that Hyper-V, WSL2 or Docker Desktop reserved at boot.
Look at what it is first. An orphaned dev server is safe to kill; a database with a write in flight is not, and neither is a system service that something else depends on. If the owner is a container, stop the container instead — killing the process the host sees only makes the runtime restart it. When the process is something you need, moving your own service to another port is the faster fix.
The listener bound to 127.0.0.1 rather than 0.0.0.0. The probes on every page print the bound address next to the process for exactly this reason: a loopback bind is reachable from the machine itself and from nowhere else, no matter how the firewall is configured. Many frameworks made that the default deliberately, so it is usually a flag rather than a bug. If the address is already 0.0.0.0 and it still fails, the next suspect is a host firewall or a cloud security group.
Barely. Internet-wide scanners sweep the whole port range continuously, so an unusual number buys hours, not safety, and it costs you every colleague who now has to remember it. It does cut the noise in your logs from opportunistic scans of the default port, which is a real if modest benefit. Authentication, a firewall that restricts source addresses, and not exposing the service at all are the measures that actually change the outcome.
Still stuck on port 53? browse every port in the reference — or go back to the failure message you actually got, above.