XX-net/XX-Net · warning
DNSOverHttpsQuery query fail:%r
Error message
DNSOverHttpsQuery query fail:%r
What it means
A DNS-over-HTTPS query failed with an unexpected exception inside query_json. The method wraps the whole JSON DoH request/parse cycle in a try/except and logs the exception %r, returning an empty IP list instead of raising. Typical underlying causes are network timeouts, TLS errors, or malformed JSON responses from the DoH server.
Source
Thrown at code/default/smart_router/local/dns_query.py:556
r = client.request("GET", url, headers={"accept": "application/dns-json"})
t2 = time.time()
ips = []
if not r:
xlog.warn("DNS server:%s domain:%s fail t:%f", self.server, domain, t2 - t0)
return ips
t = utils.to_str(r.text)
data = json.loads(t)
for answer in data["Answer"]:
ips.append(answer["data"])
self.connections.append([client, time.time()])
xlog.debug("DNS server:%s query:%s return %s t:%f", self.server, domain, ips, t2 - t0)
return ips
except Exception as e:
xlog.warn("DNSOverHttpsQuery query fail:%r", e)
return []
def query(self, domain, dns_type=1, url=None):
t0 = time.time()
try:
client = self.get_connection()
if not url:
url = self.server
# xlog.debug("DoH use %s", url)
d = DNSRecord(DNSHeader())
d.add_question(DNSQuestion(domain, dns_type))
data = d.pack()
r = client.request("POST", url, headers={"accept": "application/dns-message",
"content-type": "application/dns-message"}, body=data)
View on GitHub (pinned to cfa5bc17b6)
Solutions
- Check network reachability of the DoH server URL (curl it) and verify it returns application/dns-json responses
- Inspect the logged exception %r to identify timeout vs TLS vs parse errors
- Retry with a different DoH provider or fall back to plain UDP DNS
- Increase client timeout / reuse connections in self.connections pool
Example fix
// before
ips = doh.query_json(domain)
// after
ips = doh.query_json(domain)
if not ips:
ips = udp_resolver.query(domain) # fallback resolver Defensive patterns
Strategy: fallback
Validate before calling
def has_doh_endpoint(url):
return url.startswith("https://") and "/dns" in url Try / catch
try:
ips = doh.query_json(domain)
except Exception:
ips = []
if not ips:
ips = fallback_resolver.query(domain) Prevention
- Configure multiple DoH/UDP resolvers and fall back on empty results
- Monitor the warn log to detect a dead DoH endpoint early
- Validate the DoH URL at startup with a test query
When it happens
Trigger: Calling DNSOverHttpsQuery.query_json() when the HTTPS request to the DoH endpoint raises (connection refused, timeout, SSL verification failure), or when the response body cannot be parsed as the expected JSON DNS answer.
Common situations: DoH server URL misconfigured or unreachable, proxy blocking the DoH endpoint, server returning an HTML error page instead of DNS JSON, or Python 2/3 bytes/str issues when parsing r.text.
Related errors
- DNS server:%s domain:%s fail t:%f
- DnsOverHttpsQuery query %s cost:%f fail:%r
- DoH request no name
- query_dns_from_xxnet fail status:%d, cost=%f
- DNS s:%s query:%s fail t:%f
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/881f8a1eb79b8b3c.
Report an issue: GitHub.