{"record":{"id":"aa2e08cc06ff6c2e","repo":"thanos-io/thanos","slug":"exchange","errorCode":null,"errorMessage":"exchange","messagePattern":"exchange","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/discovery/dns/miekgdns/lookup.go","lineNumber":140,"sourceCode":"\t}\n\treturn b.String()\n}\n\n// askServerForName makes a request to a specific DNS server for a specific\n// name (and qtype). Retries with TCP in the event of response truncation,\n// but otherwise just sends back whatever the server gave, whether that be a\n// valid-looking response, or an error.\nfunc askServerForName(name string, qType dns.Type, client *dns.Client, servAddr string, edns bool) (*dns.Msg, error) {\n\tmsg := &dns.Msg{}\n\n\tmsg.SetQuestion(dns.Fqdn(name), uint16(qType))\n\tif edns {\n\t\tmsg.SetEdns0(dns.DefaultMsgSize, false)\n\t}\n\n\tresponse, _, err := client.Exchange(msg, servAddr)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"exchange\")\n\t}\n\n\tif response.Truncated {\n\t\tif client.Net == \"tcp\" {\n\t\t\treturn nil, errors.New(\"got truncated message on TCP (64kiB limit exceeded?)\")\n\t\t}\n\n\t\t// TCP fallback.\n\t\tclient.Net = \"tcp\"\n\t\treturn askServerForName(name, qType, client, servAddr, false)\n\t}\n\n\treturn response, nil\n}\n","sourceCodeStart":122,"sourceCodeEnd":155,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/discovery/dns/miekgdns/lookup.go#L122-L155","documentation":"Wraps any failure of dns.Client.Exchange — the actual network query to a DNS server. Everything from socket errors and timeouts to I/O failures during the request/response round-trip surfaces here with the original error attached.","triggerScenarios":"client.Exchange(msg, servAddr) fails: UDP/TCP timeout (default or configured timeout exceeded), network unreachable, connection refused/reset, or short/invalid response read.","commonSituations":"DNS server down or overloaded; packet loss on the network; queries dropped by egress network policy; resolv.conf pointing at a non-DNS host; timeouts set too low for slow resolvers.","solutions":["Read the wrapped underlying error (e.g. 'i/o timeout', 'connection refused') to identify the transport problem","Increase the Resolver timeout if slow resolvers are legitimately in use","Verify UDP/TCP 53 connectivity to servAddr with dig @servAddr","Fix routing/firewall/NAT issues between the client and the DNS server"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// sanity-check reachability and latency before lookups\nt0 := time.Now(); err := probeDNS(server, name); if time.Since(t0) > timeout { /* resolver too slow */ }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"exchange\") {\n    if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), \"i/o timeout\") {\n        return retryWithBackoff()\n    }\n    return err\n}","preventionTips":["Set realistic DNS timeouts on the Resolver for your network conditions","Test UDP/53 and TCP/53 reachability to each nameserver during deployment","Watch for packet loss between clients and resolvers (network monitoring)","Keep a fallback resolver (e.g. node-local or public DNS) in resolv.conf"],"tags":["dns","network","timeout"],"backgroundTag":"dns-query-timeout","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}