txthinking/brook · warning

Can not find IP

Error message

Can not find IP

What it means

Resolve6 performs a DNS AAAA lookup (after first passing through any literal IPv6 address). This error is returned when the DNS exchange succeeded (no transport error) but the answer section contained no AAAA record — i.e. the host genuinely has no IPv6 address, or the record type in the response was unexpected.

Source

Thrown at resolve.go:28

func Resolve6(host string) (string, error) {
	if net.ParseIP(host).To4() != nil {
		return "", errors.New("This is ipv4")
	}
	if net.ParseIP(host).To16() != nil {
		return host, nil
	}
	m := &dns.Msg{}
	m.SetQuestion(host+".", dns.TypeAAAA)
	r, err := dns.Exchange(m, "[2001:4860:4860::8888]:53")
	if err != nil {
		return "", err
	}
	for _, v := range r.Answer {
		if t, ok := v.(*dns.AAAA); ok {
			return t.AAAA.String(), nil
		}
	}
	return "", errors.New("Can not find IP")
}

func Resolve4(host string) (string, error) {
	if net.ParseIP(host).To4() != nil {
		return host, nil
	}
	if net.ParseIP(host).To16() != nil {
		return "", errors.New("This is ipv6")
	}
	m := &dns.Msg{}
	m.SetQuestion(host+".", dns.TypeA)
	r, err := dns.Exchange(m, "8.8.8.8:53")
	if err != nil {
		return "", err
	}
	for _, v := range r.Answer {
		if t, ok := v.(*dns.A); ok {
			return t.A.String(), nil

View on GitHub (pinned to 5cd13ef3b1)

Solutions

  1. Verify the host actually has an IPv6 record: dig AAAA <host> @8.8.8.8; if absent, fall back to Resolve4.
  2. Call Resolve6 and treat the error as 'no IPv6 available' — fall back to Resolve4(host) on error.
  3. If you passed a literal IP, confirm it is IPv6 (Resolve6 handles literals only if it checks ParseIP before; pass the address in standard form).
  4. Check network reachability to 8.8.8.8:53 (UDP 53 egress allowed) so a silent/empty response is not misread.

Example fix

// before
ip, err := Resolve6(host)
if err != nil { return err }
// after
ip, err := Resolve6(host)
if err != nil {
    // no AAAA record — fall back to IPv4
    return Resolve4(host)
}
Defensive patterns

Strategy: fallback

Validate before calling

if net.ParseIP(host) == nil {
    // optional pre-check: does the host plausibly have AAAA?
    // dig AAAA <host> can be run out-of-band
}

Type guard

func isIPv6Literal(s string) bool {
    ip := net.ParseIP(s)
    return ip != nil && ip.To4() == nil
}

Try / catch

ip, err := Resolve6(host)
if err != nil {
    ip, err = Resolve4(host)
    if err != nil { return fmt.Errorf("no address for %q: %w", host, err) }
}

Prevention

When it happens

Trigger: Calling Resolve6(host) where the DNS query to 8.8.8.8:53 returns answers but none is a *dns.AAAA record: host has only A records, NXDOMAIN/NODATA responses with empty Answer, or CNAME-only chains without a terminal AAAA.

Common situations: Looking up IPv6 for IPv4-only hosts (many services and most home networks are v4-only); querying a hostname on a DNS server that lacks AAAA records; typos in the hostname producing empty answer sections.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06). Data as JSON: /api/errors/514f1d4ca6aec9af. Report an issue: GitHub.