XX-net/XX-Net · warning

query_over_tcp %s type:%s timeout

Error message

query_over_tcp %s type:%s timeout

What it means

The TCP DNS query raised socket.timeout — either while connecting, sending, or within the recv loop — so the query is abandoned and [] returned. The socket is not returned to the connection pool. This indicates the server (or a middlebox) did not respond within the client timeout.

Source

Thrown at code/default/smart_router/local/dns_query.py:456

                xlog.warn("query_over_tcp for %s type:%d return none, cost:%f", domain, dns_type, t2-t0)

            ips = []
            for r in p.rr:
                ip = utils.to_bytes(str(r.rdata))
                if not utils.check_ip_valid(ip) and dns_type != 2:
                    if ip == domain:
                        continue

                    ip_ips = self.query(ip, dns_type)
                    ips += ip_ips
                else:
                    ips.append(ip)

            xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips, t2-t0)
            self.connections.append([sock, time.time()])
            return ips
        except socket.timeout:
            xlog.warn("query_over_tcp %s type:%s timeout", domain, dns_type)
            return []
        except Exception as e:
            xlog.exception("query_over_tcp %s type:%s except:%r", domain, dns_type, e)
            return []


class DnsOverTlsQuery(DnsOverTcpQuery):
    def __init__(self, server_list=None):
        if not server_list:
            server_list = [
                {
                    "domain": "one.one.one.one",
                    "ipv4s": [b"1.1.1.1", b"1.0.0.1"],
                },
                {
                    "domain": "dns.quad9.net",
                    "ipv4s": [b"9.9.9.9", b"149.112.112.112"],
                }

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Increase the timeout passed to the client (default is small; construct with a larger timeout)
  2. Verify reachability with 'dig +tcp @server domain' and time it
  3. Use shorter connection-pool reuse (drop connections older than a few seconds) so stale sockets aren't reused
  4. Switch to DoH/443 which is rarely filtered and has better latency characteristics
Defensive patterns

Strategy: retry

Try / catch

try:
    ips = tcp_client.query(domain, timeout=5)
except socket.timeout:
    ips = doh_client.query(domain)  # fail over transport

Prevention

When it happens

Trigger: Calling query() when the DNS server does not answer within the socket timeout: overloaded server, packet-filtering firewall silently dropping TCP 53/853, or a pooled connection that was silently closed so recv blocks forever until timeout.

Common situations: Firewalls that DROP rather than REJECT (client hangs until timeout), idle pooled connections killed by NAT/middleboxes, slow or rate-limiting resolvers, mobile networks.

Understand the failure class

Related errors


AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27). Data as JSON: /api/errors/35479b88c1db7f28. Report an issue: GitHub.