thanos-io/thanos · error

unsupported network

Error message

unsupported network %q

What it means

LookupIPAddrByNetwork only accepts the network selectors "ip4" (A records) and "ip6" (AAAA records). Any other value fails the switch before any DNS query is made and is rejected with this error, so no lookup is attempted.

Solutions

  1. Pass exactly "ip4" or "ip6" as the network argument
  2. Normalize/validate the network string before the call (trim, lowercase, map aliases like ipv4->ip4)
  3. If you need plain A/AAAA lookup without network selection, use LookupIPAddr instead
  4. For dual-stack resolution via config, use the dns.Resolve API with qtype dnsdualstack, which handles both networks

Example fix

// before
addrs, err := r.LookupIPAddrByNetwork(ctx, "tcp4", "example.com")
// after
addrs, err := r.LookupIPAddrByNetwork(ctx, "ip4", "example.com")
Defensive patterns

Strategy: validation

Validate before calling

func validNetwork(n string) bool { return n == "ip4" || n == "ip6" }
if !validNetwork(network) { return nil, fmt.Errorf("network must be ip4 or ip6, got %q", network) }

Type guard

func isDNSNetwork(s string) bool { return s == "ip4" || s == "ip6" }

Try / catch

addrs, err := r.LookupIPAddrByNetwork(ctx, network, host)
if err != nil {
    if strings.Contains(err.Error(), "unsupported network") {
        // fix the network value or fall back
    }
    return err
}

Prevention

When it happens

Trigger: Calling Resolver.LookupIPAddrByNetwork(ctx, network, host) with a network string other than exactly "ip4" or "ip6" — e.g. "ip", "tcp", "ipv4", "IP4", or an empty string. Within this repo, dns.Resolve with qtype dnsdualstack always passes valid values, so the error comes from direct callers.

Common situations: Hand-written dual-stack discovery code passing net.Dial-style network strings like "tcp4"/"udp"; case-mismatched literals like "IP4"; variables derived from config flags holding empty or mistyped network names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at pkg/discovery/dns/miekgdns/resolver.go:79

		}
	}

	return "", addrs, nil
}

func (r *Resolver) LookupIPAddr(_ context.Context, host string) ([]net.IPAddr, error) {
	return r.lookupIPAddr(host, 1, 8)
}

func (r *Resolver) LookupIPAddrByNetwork(ctx context.Context, network, host string) ([]net.IPAddr, error) {
	var qtype dns.Type
	switch network {
	case "ip6":
		qtype = dns.Type(dns.TypeAAAA)
	case "ip4":
		qtype = dns.Type(dns.TypeA)
	default:
		return nil, errors.Errorf("unsupported network %q", network)
	}
	return r.lookupIPAddrByNetwork(ctx, host, qtype, 1, 8)
}

func (r *Resolver) lookupIPAddrByNetwork(ctx context.Context, host string, qtype dns.Type, currIteration, maxIterations int) ([]net.IPAddr, error) {
	if currIteration > maxIterations {
		return nil, errors.Errorf("maximum number of recursive iterations reached (%d)", maxIterations)
	}

	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	response, err := r.lookupWithSearchPath(host, qtype)
	if err != nil {
		return nil, err

View on GitHub (pinned to 35b8b99117)