{"record":{"id":"cdb4b543db67f89b","repo":"owasp-amass/amass","slug":"failed-to-obtain-the-public-dns-csv-file-at-s-v","errorCode":null,"errorMessage":"failed to obtain the Public DNS csv file at %s: %v","messagePattern":"failed to obtain the Public DNS csv file at (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/resolvers.go","lineNumber":60,"sourceCode":"\t\"76.76.19.19\",    // Alternate DNS\n\t\"37.235.1.177\",   // FreeDNS\n\t\"77.88.8.1\",      // Yandex.DNS\n\t\"94.140.14.140\",  // AdGuard\n\t\"38.132.106.139\", // CyberGhost\n\t\"74.82.42.42\",    // Hurricane Electric\n\t\"76.76.2.0\",      // ControlD\n}\n\n// PublicResolvers includes the addresses of public resolvers obtained dynamically.\nvar PublicResolvers []string\n\n// GetPublicDNSResolvers obtains the public DNS server addresses from public-dns.info and assigns them to PublicResolvers.\nfunc GetPublicDNSResolvers() error {\n\turl := \"https://public-dns.info/nameservers-all.csv\"\n\tresp, err := amasshttp.RequestWebPage(context.Background(),\n\t\tamasshttp.DefaultClient, &amasshttp.Request{URL: url})\n\tif err != nil || resp.StatusCode < 200 || resp.StatusCode >= 400 {\n\t\treturn fmt.Errorf(\"failed to obtain the Public DNS csv file at %s: %v\", url, err)\n\t}\n\n\tvar resolvers []string\n\tvar ipIdx, reliabilityIdx int\n\tr := csv.NewReader(strings.NewReader(resp.Body))\n\tfor i := 0; ; i++ {\n\t\trecord, err := r.Read()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif i == 0 {\n\t\t\tfor idx, val := range record {\n\t\t\t\tswitch val {\n\t\t\t\tcase \"ip_address\":\n\t\t\t\t\tipIdx = idx","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/config/resolvers.go#L42-L78","documentation":"GetPublicDNSResolvers downloads the public-dns.info nameservers CSV to populate PublicResolvers. If the HTTP request fails or the status code is outside 200-399, it returns this error wrapping the cause (which is nil when a non-2xx/3xx status alone triggered it).","triggerScenarios":"Calling GetPublicDNSResolvers when https://public-dns.info/nameservers-all.csv is unreachable, returns 4xx/5xx, the network is down, or DNS/TLS for that host fails.","commonSituations":"No internet access or behind a corporate proxy; public-dns.info is down or rate-limits; TLS interception in a sandboxed CI environment; offline runs that should use local resolver config instead.","solutions":["Check network connectivity to the URL: curl -I https://public-dns.info/nameservers-all.csv.","Configure proxy environment variables (HTTP_PROXY/HTTPS_PROXY) if behind a proxy, or use a VPN.","Retry later if public-dns.info is temporarily unavailable; the error includes the wrapped cause for diagnosis.","Configure resolvers manually in the config file instead of relying on the public list.","Check resp.StatusCode in your own wrapper if you embed this — the %v is nil for pure HTTP-status failures."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Head(\"https://public-dns.info/nameservers-all.csv\")\nif err != nil || resp.StatusCode >= 400 {\n    log.Println(\"public-dns.info unreachable; using local resolver config\")\n}","typeGuard":null,"tryCatchPattern":"if err := config.GetPublicDNSResolvers(); err != nil {\n    log.Printf(\"public resolvers unavailable, falling back to config: %v\", err)\n    // proceed with configured resolvers\n}","preventionTips":["Provide local resolver config as fallback for offline use","Set proxy env vars in restricted networks","Cache a previously fetched resolver list"],"tags":["network","http","dns"],"backgroundTag":"http-request-failed","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}