XX-net/XX-Net · warning

query_dns_from_xxnet fail status:%d, cost=%f

Error message

query_dns_from_xxnet fail status:%d, cost=%f

What it means

query_dns_from_xxnet() sends a GET to dns.xx-net.org via g.x_tunnel.front_dispatcher.request to resolve a domain; if the returned HTTP status is not 200 (e.g. 404, 502, or a tunnel error code), it logs this warning with the status and elapsed time and returns an empty IP list.

Source

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

        except Exception as e:
            xlog.warn("get ip address e:%r", e)
            ips = [b'127.0.0.1']

    xlog.debug("local ips: %s", ips)
    return ips


def query_dns_from_xxnet(domain, dns_type=None):
    if not g.x_tunnel:
        return []

    t0 = time.time()
    content, status, response = g.x_tunnel.front_dispatcher.request(
        "GET", "dns.xx-net.org", path="/query?domain=%s" % (utils.to_str(domain)), timeout=5)
    t1 = time.time()

    if status != 200:
        xlog.warn("query_dns_from_xxnet fail status:%d, cost=%f", status, t1 - t0)
        return []

    if isinstance(content, memoryview):
        content = content.tobytes()

    content = utils.to_str(content)

    try:
        rs = json.loads(content)
        ips = rs["ip"]
        xlog.debug("query_dns_from_xxnet %s cost:%f return:%s", domain, t1 - t0, ips)
        #if dns_type == 1:
        #    ips = [ip for ip in ips if "." in ip]
        ips_out = []
        for ip_cn in ips:
            ip, cn = ip_cn.split("|")
            ips_out.append(ip)
        return ips_out

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Check that the X-Tunnel is connected and working (g.x_tunnel.front_dispatcher is initialized and other requests succeed).
  2. Retry the call after a short delay — transient upstream failures are common.
  3. Verify network egress to dns.xx-net.org isn't blocked by a firewall; test from another network.
  4. Inspect the numeric status in the log: 5xx points to the remote service, 4xx/0 to the tunnel or request path.

Example fix

// before
content, status, response = g.x_tunnel.front_dispatcher.request(
    "GET", "dns.xx-net.org", path="/query?domain=%s" % utils.to_str(domain), timeout=5)
if status != 200:
    xlog.warn("query_dns_from_xxnet fail status:%d, cost=%f", status, t1 - t0)
    return []

// after
for attempt in range(3):
    content, status, response = g.x_tunnel.front_dispatcher.request(
        "GET", "dns.xx-net.org", path="/query?domain=%s" % utils.to_str(domain), timeout=5)
    if status == 200:
        break
    time.sleep(1 + attempt)
else:
    xlog.warn("query_dns_from_xxnet fail after retries")
    return []
Defensive patterns

Strategy: retry

Validate before calling

if g.x_tunnel is None or not getattr(g.x_tunnel, 'front_dispatcher', None):
    raise RuntimeError('X-Tunnel front dispatcher not ready; DNS query would fail')

Try / catch

ips = query_dns_from_xxnet(domain)
if not ips:
    # returns [] on non-200 or parse failure; fall back to system DNS
    ips = socket.gethostbyname_ex(domain)[2]

Prevention

When it happens

Trigger: Calling query_dns_from_xxnet() when the X-Tunnel front dispatcher can't complete the request: the remote DNS service returns an error status, the tunnel is unhealthy, the target domain is unreachable, or the request exceeds its 5-second timeout path and reports a non-200 status.

Common situations: XX-Net tunnel not connected or front dispatcher uninitialized; dns.xx-net.org backend down or moved; GFW/network interference on the tunnel path; auth/quota issues causing an error status instead of 200; transient upstream 5xx.

Related errors


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