ginuerzh/gost · error
resolver: domain %s does not exists
Error message
resolver: domain %s does not exists
What it means
chain.DialWithOptions fails when the configured resolver (and hosts table) cannot resolve the target hostname: c.resolve returns an empty string and the dialer aborts with 'resolver: domain %s does not exists'. It means DNS resolution of the dial address failed at the resolver level, before any network connection was attempted.
Source
Thrown at chain.go:158
}
func (c *Chain) dialWithOptions(ctx context.Context, network, address string, options *ChainOptions) (net.Conn, error) {
if options == nil {
options = &ChainOptions{}
}
if c == nil {
c = &Chain{}
}
route, err := c.selectRouteFor(address)
if err != nil {
return nil, err
}
ipAddr := address
if address != "" {
ipAddr = c.resolve(address, options.Resolver, options.Hosts)
if ipAddr == "" {
return nil, fmt.Errorf("resolver: domain %s does not exists", address)
}
}
timeout := options.Timeout
if timeout <= 0 {
timeout = DialTimeout
}
var controlFunction func(_ string, _ string, c syscall.RawConn) error = nil
if c.Mark > 0 {
controlFunction = func(_, _ string, cc syscall.RawConn) error {
return cc.Control(func(fd uintptr) {
ex := setSocketMark(int(fd), c.Mark)
if ex != nil {
log.Logf("net dialer set mark %d error: %s", c.Mark, ex)
} else {
// log.Logf("net dialer set mark %d success", options.Mark)
}View on GitHub (pinned to a33fdbf4c9)
Solutions
- Verify the hostname is correct and resolvable: run `dig <domain>` or `nslookup <domain>` against the configured resolver.
- Fix the resolver configuration (correct DNS server address/port, or remove the custom resolver to use system DNS).
- Add the hostname to the Hosts table (-hosts file or Resolver hosts) as a workaround for NXDOMAIN or internal domains.
- If resolution is intermittently failing, retry or add a secondary resolver for redundancy.
Example fix
// before
dialer.DialWithOptions(ctx, "api.mycompany.internal:443", ...) // fails: resolver can't resolve
// after
resolver := net.Resolver{PreferGo: true, Dial: ...} // point at internal DNS
// or map it explicitly in hosts: 10.0.0.5 api.mycompany.internal
Defensive patterns
Strategy: validation
Validate before calling
ips, err := net.LookupHost("api.example.com")
if err != nil || len(ips) == 0 {
return fmt.Errorf("hostname not resolvable via configured resolver: %v", err)
} Try / catch
conn, err := d.DialContext(ctx, network, addr)
if err != nil {
if strings.Contains(err.Error(), "does not exists") {
// retry with fallback resolver or check hosts table
}
return err
} Prevention
- Verify hostnames with dig/nslookup against the exact resolver you configured.
- Keep a hosts file entry for internal-only domains.
- Configure at least two resolvers for redundancy.
- Watch for NXDOMAIN caused by typos or search-domain issues in containerized environments.
When it happens
Trigger: Dialing a hostname whose domain does not exist (NXDOMAIN), a resolver that cannot answer (wrong DNS server, blocked UDP 53), or Hosts/Resolver options filtering out the name so resolve() returns empty.
Common situations: Typo in the target hostname in the gost config; custom -resolver/-hosts settings pointing to an unreachable or incorrect DNS server; internal-only domains queried against public DNS; transient DNS outages.
Related errors
- empty question
- failed to create an HTTPS request: %s
- failed to perform an HTTPS request: %s
- returned status code %d
- failed to read the response body: %s
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/c7a42bbab2d5ea36.
Report an issue: GitHub.