thanos-io/thanos · error

missing port in address given for dns lookup

Error message

missing port in address given for dns lookup: %v

What it means

The dnsSD Resolver's Resolve method with qtype dns requires a host:port address because results are rebuilt as ip:port. If the name carries no port (SplitHostPort left port empty), the lookup is refused up-front with this error before any DNS query.

Solutions

  1. Append the port to the name: use "host:9090" form, e.g. "prometheus.example.com:9090"
  2. Use qtype dnssrv/dnssrvnoa instead of dns if the port should come from SRV records
  3. Fix template/config so the port placeholder is populated
  4. Remember a scheme prefix is allowed ("http://host:9090") but the port itself is still required

Example fix

// before
addresses: ["prometheus.example.com"]  // qtype dns
// after
addresses: ["prometheus.example.com:9090"]  // qtype dns
Defensive patterns

Strategy: validation

Validate before calling

_, _, err := net.SplitHostPort(name)
if err != nil { return fmt.Errorf("dns qtype requires host:port, got %q", name) }

Try / catch

res, err := resolver.Resolve(ctx, name, dns.A)
if err != nil {
    if strings.Contains(err.Error(), "missing port in address") {
        // fix config: append :port or switch to dnssrv qtype
    }
    return err
}

Prevention

When it happens

Trigger: Calling Resolve(ctx, name, A) where name has no ":port" suffix — e.g. Resolve(ctx, "prometheus.example.com", "dns") or "http://prometheus.example.com". Also happens when the scheme split eats the port or the name is malformed such that no port is parsed.

Common situations: Static SD configs listing bare hostnames without ports; copying an SRV-style entry (no port needed there) into a dns qtype entry; templated configs where the port variable is empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

	)

	schemeSplit := strings.Split(name, "//")
	if len(schemeSplit) > 1 {
		scheme = schemeSplit[0]
		name = schemeSplit[1]
	}

	// Split the host and port if present.
	host, port, err := net.SplitHostPort(name)
	if err != nil {
		// The host could be missing a port.
		host, port = name, ""
	}

	switch qtype {
	case A:
		if port == "" {
			return nil, errors.Errorf("missing port in address given for dns lookup: %v", name)
		}
		ips, err := s.resolver.LookupIPAddr(ctx, host)
		if err != nil {
			// We exclude error from std Golang resolver for the case of the domain (e.g `NXDOMAIN`) not being found by DNS
			// server. Since `miekg` does not consider this as an error,  when the host cannot be found, empty slice will be
			// returned.
			if !s.resolver.IsNotFound(err) {
				return nil, errors.Wrapf(err, "lookup IP addresses %q", host)
			}
			if ips == nil {
				level.Error(s.logger).Log("msg", "failed to lookup IP addresses", "host", host, "err", err)
			}
		}
		for _, ip := range ips {
			res = append(res, appendScheme(scheme, net.JoinHostPort(ip.String(), port)))
		}
	case SRV, SRVNoA:
		_, recs, err := s.resolver.LookupSRV(ctx, "", "", host)

View on GitHub (pinned to 35b8b99117)