Skip to content

/errors/dns/dns-resolver-nxdomain-query-name-does-not-exist

dns.resolver.NXDOMAIN: The DNS query name does not exist

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
DNS
exit code
1
versions
dnspython 2.x
os
any

dns.resolver.NXDOMAIN: The DNS query name does not exist: typo.example.test. is raised by Python's dnspython when the DNS server answers with rcode NXDOMAIN: the name does not exist at all, for any record type. That is a definite answer, not a network problem. Check the spelling and the zone. If the name exists but has no record of the type you asked for, dnspython raises dns.resolver.NoAnswer instead.

Reproduce it

A tiny DNS server on 127.0.0.1, written with dnspython, that knows only app.example.test (A record), and a resolver pointed at it:

bash
cat > nx.py <<'EOF'
import socket, threading
import dns.message, dns.rcode, dns.rdatatype, dns.resolver, dns.rrset

def serve(sock):
    while True:
        data, addr = sock.recvfrom(4096)
        q = dns.message.from_wire(data)
        r = dns.message.make_response(q)
        name = q.question[0].name.to_text()
        if name == "app.example.test.":
            if q.question[0].rdtype == dns.rdatatype.A:
                r.answer.append(dns.rrset.from_text(name, 300, "IN", "A", "192.0.2.10"))
        else:
            r.set_rcode(dns.rcode.NXDOMAIN)
        sock.sendto(r.to_wire(), addr)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("127.0.0.1", 4925))
threading.Thread(target=serve, args=(s,), daemon=True).start()

res = dns.resolver.Resolver(configure=False)
res.nameservers = ["127.0.0.1"]
res.port = 4925
for name, rtype in [("app.example.test", "A"), ("typo.example.test", "A"), ("app.example.test", "AAAA")]:
    try:
        print(name, rtype, "->", [r.to_text() for r in res.resolve(name, rtype)])
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer) as e:
        print(name, rtype, "->", f"{type(e).__module__}.{type(e).__name__}: {e}")
EOF
uv run -q --no-project --python 3.13 --with dnspython==2.8.0 python nx.py

Output

app.example.test A -> ['192.0.2.10']
typo.example.test A -> dns.resolver.NXDOMAIN: The DNS query name does not exist: typo.example.test.
app.example.test AAAA -> dns.resolver.NoAnswer: The DNS response does not contain an answer to the question: app.example.test. IN AAAA

NXDOMAIN vs NoAnswer vs timeouts

ExceptionDNS answerMeaning
dns.resolver.NXDOMAINrcode NXDOMAINThe name does not exist for any type
dns.resolver.NoAnswerrcode NOERROR, empty answerThe name exists, but has no record of this type (often AAAA or MX)
dns.resolver.NoNameserversSERVFAIL or REFUSED from every serverThe servers could not or would not answer
dns.resolver.LifetimeTimeoutNo answer in timeNetwork or resolver problem; retry or check connectivity
python
import dns.resolver
try:
    answers = dns.resolver.resolve("example.org", "MX")
except dns.resolver.NXDOMAIN:
    ...  # the domain does not exist: report it, do not retry
except dns.resolver.NoAnswer:
    ...  # no MX: fall back to the A record, as mail servers do

Pass raise_on_no_answer=False to resolve() to get an empty answer instead of NoAnswer. NXDOMAIN is always raised, because there is no answer section to return.

Check the zone

NXDOMAIN from a recursive resolver can be a cached negative answer (kept for the SOA minimum TTL). Ask the authoritative server directly to see the current state: dig typo.example.com @ns1.example.com. If it answers, flush or wait out the negative cache of your resolver.

Sources