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
- Append the port to the name: use "host:9090" form, e.g. "prometheus.example.com:9090"
- Use qtype dnssrv/dnssrvnoa instead of dns if the port should come from SRV records
- Fix template/config so the port placeholder is populated
- 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
- Always write host:port in static SD addresses for qtype dns
- Use dnssrv/dnssrvnoa when ports come from SRV records
- Validate address templates render with a non-empty port
- A scheme prefix is fine but does not replace the port
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.
- DNS resolution errors: ENOTFOUND and getaddrinfo failures — how hostname lookups fail and how to debug them.
Related errors
- failed to parse template
- failed to execute template
- error while parsing config for request logging
- getting http client config
- parsing http config YAML
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)