thanos-io/thanos · error
lookup SRV records
Error message
lookup SRV records %q
What it means
For qtype dnssrv/dnssrvnoa, Resolve calls LookupSRV for the host. Failures other than NotFound are wrapped as "lookup SRV records <host>" and returned, meaning the SRV query itself failed (as opposed to the record simply not existing).
Solutions
- Verify the SRV record exists and the server responds: dig SRV _service._proto.example.com
- Check DNS server connectivity and timeouts; inspect errors.Cause of the wrapped error
- Use qtype dns if the target is a plain A record rather than an SRV-based service
- If NotFound was intended to be tolerated, confirm the name; NotFound is already tolerated and only logged
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check SRV availability
_, recs, err := net.LookupSRV("", "", srvName)
if err != nil && !isNXDOMAIN(err) { /* SRV query will likely fail in the library too */ } Try / catch
res, err := resolver.Resolve(ctx, srvName, dns.SRV)
if err != nil {
if strings.Contains(err.Error(), "lookup SRV records") {
cause := errors.Cause(err)
// log cause; retry on timeout, alert on persistent failure
}
return err
} Prevention
- Verify SRV records with dig SRV before configuring discovery
- Ensure the DNS server actually serves the SRV zone (some servers error instead of NXDOMAIN)
- Keep SRV-answer CNAME chains short to avoid the recursion cap
- Include the full _service._proto prefix in the configured name
When it happens
Trigger: Resolve(ctx, "_grpc._tcp.example.com", "dnssrv") where the SRV query errors: DNS server unreachable, timeout, SERVFAIL, malformed response, or non-NotFound errors from the underlying resolver (including the SRV recursion-cap error from CNAME loops in SRV answers).
Common situations: Misconfigured SRV discovery names (querying a zone without SRV support via a server that errors rather than NXDOMAINs); DNS outage/firewall blocking UDP/TCP 53; rooted-name issues where the query target is wrong.
Related errors
- lookup IP addresses
- no such host
- could not resolve : all servers responded with errors to at…
- resolution against server
- exchange
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/40bcc9d72554e949.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/discovery/dns/resolver.go:102
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)
if err != nil {
if !s.resolver.IsNotFound(err) {
return nil, errors.Wrapf(err, "lookup SRV records %q", host)
}
if len(recs) == 0 {
level.Error(s.logger).Log("msg", "failed to lookup SRV records", "host", host, "err", err)
}
}
for _, rec := range recs {
// Only use port from SRV record if no explicit port was specified.
resPort := port
if resPort == "" {
resPort = strconv.Itoa(int(rec.Port))
}
if qtype == SRVNoA {
// Remove the final dot from rooted DNS names (this is for compatibility with Prometheus)
target := strings.TrimRight(rec.Target, ".")
res = append(res, appendScheme(scheme, net.JoinHostPort(target, resPort)))
continueView on GitHub (pinned to 35b8b99117)