ginuerzh/gost · error

resolver: domain 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.

Solutions

  1. Verify the hostname is correct and resolvable: run `dig <domain>` or `nslookup <domain>` against the configured resolver.
  2. Fix the resolver configuration (correct DNS server address/port, or remove the custom resolver to use system DNS).
  3. Add the hostname to the Hosts table (-hosts file or Resolver hosts) as a workaround for NXDOMAIN or internal domains.
  4. 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

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


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/c7a42bbab2d5ea36. Report an issue: GitHub.

Appendix: 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)