XX-net/XX-Net · warning

query_by_system %s %d e:%r

Error message

query_by_system %s %d e:%r

What it means

query_by_system() wraps socket.gethostbyname() and logs this warning when the OS resolver fails to resolve the domain. It returns an empty IP list; it does not raise. Causes include NXDOMAIN, resolver timeouts, DNS service down, or an invalid hostname string.

Source

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

            if utils.check_ip_valid4(server_ip):
                self.sock.sendto(req4_pack, (server_ip, 53))
            else:
                self.sock6.sendto(req4_pack, (server_ip, 53))
        except Exception as e:
            xlog.warn("send_request except:%r", e)

    def query_by_system(self, domain, dns_type):
        ips = []
        try:
            t0 = time.time()
            ip = socket.gethostbyname(domain)
            t1 = time.time()
            ips.append(ip)

            xlog.debug("query_by_system, %s %d cost:%f, return:%s", domain, dns_type, t1 - t0, ips)
        except Exception as e:
            xlog.warn("query_by_system %s %d e:%r", domain, dns_type, e)

        return ips

    def query(self, domain, dns_type=1, timeout=3):
        if sys.platform == "ios":
            return self.query_by_system(domain, dns_type)

        t0 = time.time()
        end_time = t0 + timeout
        while True:
            id = random.randint(0, 65535)
            if id not in self.waiters:
                break

        que = Queue()
        que.domain = domain

        for server_ip in self.dns_server:

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Confirm the domain actually resolves: 'nslookup domain' on the same machine
  2. Fix the host's system resolver configuration (/etc/resolv.conf, systemd-resolved status)
  3. Pass a real, fully-qualified domain name; avoid empty strings and trailing junk
  4. If the system resolver is unreliable, route queries through the module's UDP/TCP/DoT/DoH clients instead of query_by_system
Defensive patterns

Strategy: fallback

Validate before calling

import socket
def resolves(domain):
    try:
        socket.gethostbyname(domain)
        return True
    except socket.gaierror:
        return False

Try / catch

ips = dns.query(domain)
if not ips:  # query_by_system never raises; it returns []
    handle_unresolvable(domain)

Prevention

When it happens

Trigger: Calling query()/query_by_system() with a non-existent domain (NXDOMAIN), an empty or malformed hostname, or when the host's system resolver (see /etc/resolv.conf, systemd-resolved, mDNS) is unavailable or times out. Also the default path on iOS (sys.platform == 'ios').

Common situations: Typos in domain names, testing with fake domains, container/systemd-resolved breakage, macOS/ iOS where gethostbyname goes through mDNSResponder and the network is flaky.

Related errors


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