XTLS/Xray-core · error
not an IP address:{}
Error message
not an IP address:{} What it means
Returned by NameServerConfig.Build in infra/conf/dns.go when the per-server 'clientIp' field parses to a domain rather than an IP. Family().IsIP() is false for domains, so Xray rejects it with the offending value appended — DNS client IP must be a literal IPv4/IPv6 address.
Source
Thrown at infra/conf/dns.go:131
} else {
newUnexpectedIPs = append(newUnexpectedIPs, s)
}
}
expectedIPRules, err := geodata.ParseIPRules(newExpectedIPs)
if err != nil {
return nil, err
}
unexpectedIPRules, err := geodata.ParseIPRules(newUnexpectedIPs)
if err != nil {
return nil, err
}
var myClientIP []byte
if c.ClientIP != nil {
if !c.ClientIP.Family().IsIP() {
return nil, errors.New("not an IP address:", c.ClientIP.String())
}
myClientIP = []byte(c.ClientIP.IP())
}
return &dns.NameServer{
Address: &net.Endpoint{
Network: net.Network_UDP,
Address: c.Address.Build(),
Port: uint32(c.Port),
},
ClientIp: myClientIP,
SkipFallback: c.SkipFallback,
Domain: domainRules,
ExpectedIp: expectedIPRules,
QueryStrategy: resolveQueryStrategy(c.QueryStrategy),
ActPrior: actPrior,
Tag: c.Tag,
TimeoutMs: c.TimeoutMs,View on GitHub (pinned to 7d214f8b09)
Solutions
- Set clientIp to a local literal IP: "clientIp": "192.168.1.10"
- Put server hostnames in 'address', never in 'clientIp'
- Omit clientIp entirely if you do not need to pin the query source
Example fix
// before
{"address": "1.1.1.1", "clientIp": "myhost.example.com"}
// after
{"address": "1.1.1.1", "clientIp": "192.168.1.10"} Defensive patterns
Strategy: type-guard
Validate before calling
func isLiteralIP(s string) bool {
return net.ParseIP(s) != nil
} Type guard
func isClientIPValid(v any) bool {
s, ok := v.(string)
return ok && net.ParseIP(s) != nil
} Try / catch
if _, err := nsc.Build(); err != nil {
if strings.Contains(err.Error(), "not an IP address") {
return fmt.Errorf("clientIp %s must be a literal IP, not a domain", nsc.ClientIP)
}
return err
} Prevention
- clientIp accepts only literal IPv4/IPv6
- Hostnames belong in 'address', never 'clientIp'
When it happens
Trigger: {"address": "1.1.1.1", "clientIp": "example.com"} or clientIp set to an env: name resolving to a hostname. The string unmarshals fine (no error at parse time); failure happens only at Build.
Common situations: Confusing clientIp (source address for DNS queries) with the DNS server address; putting the server hostname in clientIp; env var pointing at a DDNS name.
Related errors
- failed to parse name server: {}
- nameserver address is not specified
- invalid address
- invalid DNS hosts
- unknown action: {}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/789d969ff6a54e5f.
Report an issue: GitHub.