XX-net/XX-Net · warning

DnsOverTlsQuery connect %s %s:%d fail:%r

Error message

DnsOverTlsQuery connect %s %s:%d fail:%r

What it means

DnsOverTlsQuery.connect() failed to establish a DNS-over-TLS session: it picked a random IPv4 from the server's bootstrap IPs, connected via the parent connect(), then wrapped the socket in TLS with wrap_socket(server_hostname=domain). Any failure in either step logs this warning and returns None.

Source

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

                    "ipv4s": [b"9.9.9.9", b"149.112.112.112"],
                }
            ]

        DnsOverTcpQuery.__init__(self, server_list=server_list, port=853)
        self.protocol = "DoT"
        self.ssl_context = ssl.create_default_context()
        self.ssl_context.check_hostname = False
        self.ssl_context.verify_mode = ssl.CERT_REQUIRED

    def connect(self, host, port):
        domain = host["domain"]
        ipv4 =  random.choice(host["ipv4s"])
        try:
            s = super(DnsOverTlsQuery, self).connect(ipv4, port)
            sock = self.ssl_context.wrap_socket(s, server_hostname=domain)
            return sock
        except Exception as e:
            xlog.warn("DnsOverTlsQuery connect %s %s:%d fail:%r", ipv4, domain, port, e)
            return None


class DnsOverHttpsQuery(object):
    def __init__(self, timeout=6):
        self.protocol = "DoH"
        self.timeout = timeout
        self.cn_servers = ["https://1.12.12.12/dns-query", "https://223.5.5.5/dns-query"]
        self.other_servers = [
            "https://1.1.1.1/dns-query",
            "https://dns10.quad9.net/dns-query",
            "https://dns.aa.net.uk/dns-query",
        ]
        self.connection_timeout = 60
        self.connections = []

    def get_connection(self):
        while len(self.connections):

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Test DoT reachability: 'openssl s_client -connect 1.1.1.1:853 -servername cloudflare-dns.com'
  2. If 853 is blocked, switch to DnsOverHttpsQuery (DoH over 443)
  3. Refresh the bootstrap ipv4s list for the resolver host
  4. Ensure the ssl_context CA bundle is current so certificate validation succeeds
Defensive patterns

Strategy: fallback

Validate before calling

import socket
def dot_reachable(ip, port=853, timeout=3):
    try:
        s = socket.create_connection((ip, port), timeout)
        s.close()
        return True
    except OSError:
        return False
servers = [ip for ip in host['ipv4s'] if dot_reachable(ip)]

Try / catch

sock = dot_client.connect(host, port)
if sock is None:
    sock = doh_client.connect(host, 443)  # DoH fallback

Prevention

When it happens

Trigger: Randomly selecting a dead/unreachable IPv4 from host['ipv4s']; TCP 853 blocked by the firewall; TLS handshake failure — certificate mismatch/expire, unsupported TLS version, SNI-based blocking, or protocol corruption by a middlebox.

Common situations: DoT on port 853 blocked by ISPs/corporate firewalls (very common), stale bootstrap IPs for the resolver, TLS-intercepting proxies rejecting the DoT certificate, outdated CA bundle for the ssl_context.

Related errors


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