thanos-io/thanos · error

lookup IP addresses (dual-stack)

Error message

lookup IP addresses (dual-stack) %q

What it means

In the ADualStack branch of Resolve, lookups run on both 'ip6' and 'ip4' networks and each error is collected into an errutil.MultiError. If no IP addresses were obtained at all AND at least one lookup errored, the resolver wraps and returns the combined error. It means dual-stack DNS resolution completely failed (both address families), not partially.

Solutions

  1. Run nslookup/dig for the hostname with both A and AAAA queries to see why resolution fails.
  2. Fix DNS configuration (resolv.conf, CoreDNS, kube-dns) or network rules blocking port 53.
  3. Correct the hostname in the discovery config; check for typos or removed services.
  4. Wrap Resolve in retry with backoff for transient DNS failures.

Example fix

// before
ips, err := resolver.Resolve(ctx, []string{"dnsdualstack+http://missing-svc:9090"})
// after
ips, err := resolver.Resolve(ctx, []string{"dnsdualstack+http://existing-svc:9090"})
if err != nil {
    var dnsErr *net.DNSError
    if errors.As(err, &dnsErr) && dnsErr.IsTemporary {
        err = backoff.Retry(func() error { _, err = resolver.Resolve(ctx, addrs); return err }, b)
    }
}
Defensive patterns

Strategy: retry

Validate before calling

func canResolveDualStack(host string) error {
    for _, netw := range []string{"ip4", "ip6"} {
        if _, err := net.DefaultResolver.LookupIPAddr(context.Background(), netw, host); err != nil {
            return fmt.Errorf("%s lookup for %q failed: %w", netw, host, err)
        }
    }
    return nil
}

Try / catch

ips, err := resolver.Resolve(ctx, addrs)
if err != nil {
    var dnsErr *net.DNSError
    if errors.As(err, &dnsErr) && dnsErr.IsTemporary {
        return backoff.Retry(func() error { _, err = resolver.Resolve(ctx, addrs); return err }, b)
    }
    return err // permanent: bad host or DNS misconfig
}

Prevention

When it happens

Trigger: Calling Resolve with an ADualStack address where LookupIPAddrByNetwork fails for both ip6 and ip4 — hostname does not exist (NXDOMAIN), DNS server unreachable, or ctx canceled — and zero addresses were collected.

Common situations: DNS outages or broken resolv.conf in Kubernetes pods; typo'd or deleted service hostnames; a host with neither AAAA nor A records; network policies blocking egress to DNS (port 53).

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/55156c0a10c854b4. Report an issue: GitHub.

Appendix: source

Thrown at pkg/discovery/dns/resolver.go:155

		if port == "" {
			return nil, errors.Errorf("missing port in address given for dnsdualstack lookup: %v", name)
		}
		var ips []net.IPAddr
		lookupErrs := errutil.MultiError{}

		for _, network := range []string{"ip6", "ip4"} {
			addrs, err := s.resolver.LookupIPAddrByNetwork(ctx, network, host)
			if err != nil {
				if !s.resolver.IsNotFound(err) {
					lookupErrs.Add(err)
				}
				continue
			}
			ips = append(ips, addrs...)
		}

		if err := lookupErrs.Err(); len(ips) == 0 && err != nil {
			return nil, errors.Wrapf(err, "lookup IP addresses (dual-stack) %q", host)
		}

		for _, ip := range ips {
			res = append(res, appendScheme(scheme, net.JoinHostPort(ip.String(), port)))
		}
	default:
		return nil, errors.Errorf("invalid lookup scheme %q", qtype)
	}

	if res == nil && err == nil {
		level.Warn(s.logger).Log("msg", "IP address lookup yielded no results. No host found or no addresses found", "host", host)
	}

	return res, nil
}

func appendScheme(scheme, host string) string {
	if scheme == "" {

View on GitHub (pinned to 35b8b99117)