XX-net/XX-Net · warning
DNS query:%s not valid, type:%d
Error message
DNS query:%s not valid, type:%d
What it means
The caller asked to resolve a hostname that failed the is_valid_hostname check (bad characters, wrong label length, or empty), so the resolver refuses to query and returns []. This is input validation, not a network failure.
Source
Thrown at code/default/smart_router/local/dns_query.py:673
def query_unknown_domain(self, domain, dns_type):
res = self.local_dns_resolve.query(domain, dns_type)
if res:
return res
return self.parallel_query.query(domain, dns_type, [
self.https_query.query,
self.tls_query.query,
self.tcp_query.query,
query_dns_from_xxnet
])
def query(self, domain, dns_type=1, history=[]):
domain = utils.to_bytes(domain)
if utils.check_ip_valid(domain):
return [domain]
if not self.is_valid_hostname(domain):
xlog.warn("DNS query:%s not valid, type:%d", domain, dns_type)
return []
ips = g.domain_cache.get_ips(domain, dns_type)
if ips:
return ips
rule = g.user_rules.check_host(domain, 0)
if rule == "black":
# user define black list like advertisement or malware server.
ips = ["127.0.0.1"]
xlog.debug("DNS query:%s in black", domain)
return ips
elif b"." not in domain or g.gfwlist.in_white_list(domain) or rule in ["direct"] or g.config.pac_policy == "all_Direct":
ips = self.local_dns_resolve.query(domain, timeout=1)
g.domain_cache.set_ips(domain, ips, dns_type)
return ips
View on GitHub (pinned to cfa5bc17b6)
Solutions
- Log/sanitize the domain before querying: strip invalid characters, verify label lengths
- Fix the upstream code that produced the malformed hostname (e.g. URL parser)
- Relax is_valid_hostname if underscores must be supported for internal names
Example fix
// before
ips = resolver.query(domain)
// after
if not resolver.is_valid_hostname(domain):
domain = sanitize(domain) # strip invalid chars, truncate labels
ips = resolver.query(domain) Defensive patterns
Strategy: validation
Validate before calling
def is_queryable(domain):
return bool(domain) and len(domain) <= 253 and all(
0 < len(l) <= 63 and all(c.isalnum() or c == '-' for c in l)
for l in domain.rstrip('.').split('.')) Type guard
def is_valid_domain_name(d: bytes) -> bool:
try:
name = d.decode('idna') if isinstance(d, bytes) else d
return is_queryable(name.lower().strip('.'))
except Exception:
return False Prevention
- Normalize and validate hostnames at the boundary where they enter your system
- Never feed raw SNI/URL fragments into the resolver
- Strip trailing dots and lowercase before validating
When it happens
Trigger: Calling BaseResolver.query() (or subclass) with a domain containing invalid characters, labels longer than 63 chars, total length over 253, or a malformed name produced by upstream parsing.
Common situations: Passing a hostname with underscores or wildcards, a trailing artifact like a null byte, or garbage extracted from a URL/SNI field; some browsers/apps generate names with underscores that strict validators reject.
Understand the failure class
- DNS resolution errors: ENOTFOUND and getaddrinfo failures — how hostname lookups fail and how to debug them.
Related errors
- Servers could not be resolved, %r.
- DoH request no name
- query_dns_from_xxnet fail status:%d, cost=%f
- query_dns_from_xxnet %s json:%s parse fail:%s
- remove local DNS server %s from upstream
AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27).
Data as JSON: /api/errors/8e5cfd4107d67ac5.
Report an issue: GitHub.