{"record":{"id":"87cd6fb88b106680","repo":"XX-net/XX-Net","slug":"dns-s-s-query-s-fail-t-f","errorCode":null,"errorMessage":"DNS s:%s query:%s fail t:%f","messagePattern":"DNS s:(.+?) query:(.+?) fail t:(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/smart_router/local/dns_query.py","lineNumber":578,"sourceCode":"        t0 = time.time()\n        try:\n            client = self.get_connection()\n\n            if not url:\n                url = self.server\n            # xlog.debug(\"DoH use %s\", url)\n\n            d = DNSRecord(DNSHeader())\n            d.add_question(DNSQuestion(domain, dns_type))\n            data = d.pack()\n\n            r = client.request(\"POST\", url, headers={\"accept\": \"application/dns-message\",\n                                                     \"content-type\": \"application/dns-message\"}, body=data)\n\n            t2 = time.time()\n            ips = []\n            if not r:\n                xlog.warn(\"DNS s:%s query:%s fail t:%f\", self.server, domain,  t2 - t0)\n                return ips\n\n            p = DNSRecord.parse(r.text)\n\n            self.connections.append([client, time.time()])\n\n            for r in p.rr:\n                ip = utils.to_bytes(str(r.rdata))\n                if not utils.check_ip_valid(ip):\n                    if ip == domain:\n                        continue\n\n                    ip_ips = self.query(ip, dns_type)\n                    ips += ip_ips\n                else:\n                    ips.append(ip)\n\n            xlog.debug(\"DNS %s %s return %s t:%f\", self.protocol, domain, ips, t2 - t0)","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/smart_router/local/dns_query.py#L560-L596","documentation":"The DoH server returned a falsy/empty response object for the POSTed wire-format DNS query, so the code logs 'fail' with the elapsed time and returns an empty IP list. It indicates the HTTP layer completed without raising but produced no usable response (empty body, connection reset swallowed by the client, etc.).","triggerScenarios":"Calling query() where client.request('POST', url, ...) returns None or an empty response — e.g. the HTTP client failed silently, the connection was closed mid-request, or the server replied with an empty body.","commonSituations":"Flaky connection pool reuse after a server closes keep-alive connections, DoH endpoint behind a flaky proxy, server-side rate limiting returning empty responses.","solutions":["Discard the pooled connection and retry once with a fresh connection","Verify the DoH URL accepts POST with content-type application/dns-message (curl -H)","Check for proxy interference on the connection","Fall back to another resolver on empty result"],"exampleFix":"// before\nr = client.request(\"POST\", url, headers=..., body=data)\n// after\nr = client.request(\"POST\", url, headers=..., body=data)\nif not r:\n    self.connections = []  # drop stale pooled connections\n    r = client.request(\"POST\", url, headers=..., body=data)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    ips = doh.query(domain)\n    if ips:\n        break\n    doh.reset_connections()  # drop stale pooled sockets","preventionTips":["Detect empty responses and retry once with a fresh connection","Keep the connection pool small or TTL-bounded","Health-check the DoH endpoint periodically"],"tags":["dns","doh","http","empty-response"],"backgroundTag":"dns-resolution-failed","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}