XTLS/Xray-core · error · errors.Error
failed to get IP address for domain {domain}
Error message
failed to get IP address for domain {domain} What it means
With domainStrategy UseIP/UseIPv4/UseIPv6, freedom resolves the destination domain itself before dialing. On the first resolve it queries the system resolver for A records (if IPv4 routes exist) then AAAA (if IPv6 routes exist); if both come back empty, it fails with this error naming the domain. The lookup uses Go's net.DefaultResolver, so it follows /etc/resolv.conf and the OS.
Source
Thrown at proxy/freedom/freedom.go:322
Address: net.IPAddress(ips[dice.Roll(len(ips))]),
Port: dialDest.Port,
}
errors.LogInfo(ctx, "dialing to ", dialDest)
}
} else if h.shouldResolveDomainBeforeFinalRules(dialDest, defaultRule) { // asis + domain + hasrules
domain := dialDest.Address.Domain()
var ips []net.IP
if firstResolve {
firstResolve = false
supportIPv4, supportIPv6 := utils.CheckRoutes()
if supportIPv4 {
ips, _ = net.DefaultResolver.LookupIP(ctx, "ip4", domain)
}
if len(ips) == 0 && supportIPv6 {
ips, _ = net.DefaultResolver.LookupIP(ctx, "ip6", domain)
}
if len(ips) == 0 {
return errors.New("failed to get IP address for domain ", domain)
}
} else {
ips, _ = net.DefaultResolver.LookupIP(ctx, "ip", domain)
}
if len(ips) == 0 { // SRV/TXT, lookup failed
return errors.New("failed to get IP address for domain ", domain)
}
if addr := net.IPAddress(ips[dice.Roll(len(ips))]); addr != nil {
dialDest.Address = addr
errors.LogInfo(ctx, "dialing to ", dialDest)
}
}
if rule := h.matchFinalRule(dialDest.Network, dialDest.Address, dialDest.Port, defaultRule); rule != nil && rule.action == RuleAction_Block {
blockedDest = &dialDest
blockedRule = rule
return nil
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- From the Xray host, run `dig <domain> A +short` and `dig <domain> AAAA +short` to confirm the system resolver returns records
- Fix /etc/resolv.conf or the container's DNS settings so net.DefaultResolver works
- If DNS is intentionally handled elsewhere, set domainStrategy to "AsIs" so freedom dials by name
- Verify the host actually has IPv4/IPv6 routes (CheckRoutes gates the lookups)
Example fix
// before
"settings": { "domainStrategy": "UseIP" }
// after (let remote/proxy resolve, or fix host DNS first)
"settings": { "domainStrategy": "AsIs" } Defensive patterns
Strategy: validation
Validate before calling
```go
if ips, err := net.DefaultResolver.LookupIP(ctx, "ip", domain); err != nil || len(ips) == 0 {
// skip UseIP strategy or fail fast with a clear reason
}
``` Prevention
- Health-check host DNS before enabling UseIP/UseIPv4/UseIPv6
- Prefer AsIs when a remote resolver is authoritative
- Confirm IPv4/IPv6 routes exist (CheckRoutes gates lookups)
When it happens
Trigger: destination.domainStrategy set to UseIP/UseIPv4/UseIPv6 plus a domain that returns no A/AAAA records (NXDOMAIN, DNS-only-HTTPS records), or a broken system resolver on the Xray host. Also triggered when CheckRoutes() reports no usable IPv4/IPv6 route so both lookups are skipped.
Common situations: Host with no DNS configured (containers with empty resolv.conf), IPv6 disabled at the OS but strategy forcing ip6, typo'd domain, or a resolver that filters records. Because the error is swallowed into `ips, _`, the real DNS error is invisible — check with `dig @<resolver> <domain> A` on the host.
Related errors
- failed to resolve ip for target ${domain}
- failed to parse name server: {}
- nameserver address is not specified
- not an IP address:{}
- invalid address
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/8780b818e4971ad1.
Report an issue: GitHub.