{"record":{"id":"130be8e43c1ab6be","repo":"thanos-io/thanos","slug":"could-not-load-resolv-conf-s","errorCode":null,"errorMessage":"could not load resolv.conf: %s","messagePattern":"could not load resolv\\.conf: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/discovery/dns/miekgdns/lookup.go","lineNumber":49,"sourceCode":"//     the servers in the \"nameservers\" list with the answer \"that name does\n//     not exist\" (NXDOMAIN).  In that case, it can be considered\n//     pseudo-authoritative that there are no records for that name.\n//\n//  3. One or more of the names was responded to by all servers with some\n//     sort of error indication.  In that case, we can't know if, in fact,\n//     there are records for the name or not, so whatever state the\n//     configuration is in, we should keep it that way until we know for\n//     sure (by, presumably, all the names getting answers in the future).\n//\n// Outcomes 1 and 2 are indicated by a valid response message (possibly an\n// empty one) and no error.  Outcome 3 is indicated by an error return.  The\n// error will be generic-looking, because trying to return all the errors\n// returned by the combination of all name permutations and servers is a\n// nightmare.\nfunc (r *Resolver) lookupWithSearchPath(name string, qtype dns.Type) (*dns.Msg, error) {\n\tconf, err := dns.ClientConfigFromFile(r.ResolvConf)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"could not load resolv.conf: %s\", err)\n\t}\n\n\tvar errs []error\n\tfor _, lname := range conf.NameList(name) {\n\t\tresponse, err := lookupFromAnyServer(lname, qtype, conf)\n\t\tif err != nil {\n\t\t\t// We can't go home yet, because a later name\n\t\t\t// may give us a valid, successful answer.  However\n\t\t\t// we can no longer say \"this name definitely doesn't\n\t\t\t// exist\", because we did not get that answer for\n\t\t\t// at least one name.\n\t\t\terrs = append(errs, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif response.Rcode == dns.RcodeSuccess {\n\t\t\t// Outcome 1: GOLD!\n\t\t\treturn response, nil","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/discovery/dns/miekgdns/lookup.go#L31-L67","documentation":"This error wraps a failure to read/parse the resolv.conf file before any DNS query is made. dns.ClientConfigFromFile could not open or parse the file at Resolver.ResolvConf, so lookupWithSearchPath aborts with the wrapped error including the underlying message.","triggerScenarios":"Constructing a Resolver with a ResolvConf path that does not exist, is unreadable (permissions), or contains malformed resolv.conf syntax, then calling any lookup method (lookupSRV, lookupIPAddr, lookupIPAddrByNetwork).","commonSituations":"Wrong custom resolv.conf path passed to the DNS SD config; file deleted in a container image; bind-mount missing in a container; corrupted or hand-edited resolv.conf with invalid directives.","solutions":["Verify the resolv.conf path exists and is readable: ls -l /etc/resolv.conf (or your custom path) and cat it to check it parses","Fix the resolv_conf_file path in your DNS SD discovery configuration to point at a valid file","In containers, ensure the file is mounted (e.g. Kubernetes injects /etc/resolv.conf automatically; custom images must not delete it)","Inspect the wrapped error text after 'could not load resolv.conf: ...' to distinguish open failure from parse failure"],"exampleFix":"// before\nresolver, _ := miekgdns.NewResolver(30*time.Second, \"nope\", \"/etc/missing-resolv.conf\")\n// after\nresolver, _ := miekgdns.NewResolver(30*time.Second, \"nope\", \"/etc/resolv.conf\")","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(resolvConfPath); err != nil {\n    return fmt.Errorf(\"resolv.conf %s unavailable: %w\", resolvConfPath, err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := r.LookupIPAddr(ctx, name); err != nil {\n    if strings.Contains(err.Error(), \"could not load resolv.conf\") {\n        return fmt.Errorf(\"DNS discovery misconfigured: %w\", err)\n    }\n    return err\n}","preventionTips":["Stat/open the resolv.conf path at config-load time and fail fast","In containers, never delete or override /etc/resolv.conf unless providing a valid replacement","Use absolute paths for custom resolv.conf files and mount them explicitly in Kubernetes","Parse-validate the file (dns.ClientConfigFromFile) in an init/health check"],"tags":["dns","resolv-conf","file-not-found","configuration"],"backgroundTag":"config-file-not-found","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"}