{"record":{"id":"023bbea7f2b6ebf6","repo":"coredns/coredns","slug":"no-nameservers-found","errorCode":null,"errorMessage":"no nameservers found","messagePattern":"no nameservers found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugin/pkg/parse/host.go","lineNumber":16,"sourceCode":"package parse\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/coredns/coredns/plugin/pkg/transport\"\n\n\t\"github.com/miekg/dns\"\n)\n\n// ErrNoNameservers is returned by HostPortOrFile if no servers can be parsed.\nvar ErrNoNameservers = errors.New(\"no nameservers found\")\n\n// Strips the zone, but preserves any port that comes after the zone\nfunc stripZone(host string) string {\n\tif strings.Contains(host, \"%\") {\n\t\tlastPercent := strings.LastIndex(host, \"%\")\n\t\tnewHost := host[:lastPercent]\n\t\treturn newHost\n\t}\n\treturn host\n}\n\n// HostPortOrFile parses the strings in s, each string can either be a\n// address, [scheme://]address:port or a filename. The address part is checked\n// and in case of filename a resolv.conf like file is (assumed) and parsed and\n// the nameservers found are returned.\nfunc HostPortOrFile(s ...string) ([]string, error) {\n\tvar servers []string\n\tfor _, h := range s {","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/coredns/coredns/blob/558c9757a92b361e550bdba82d0b4ddf3d12d595/plugin/pkg/parse/host.go#L1-L34","documentation":"parse.ErrNoNameservers is a sentinel error from CoreDNS's parse package, returned by HostPortOrFile (and classifyToAddrs) when resolv.conf-style input yields zero usable nameservers. The forward/resolve code explicitly checks for it with errors.Is and skips the source instead of failing, because an empty nameserver list is often benign (e.g. an empty file).","triggerScenarios":"HostPortOrFile parses a resolv.conf (or file/direct config) that contains no valid nameserver entries, so len(servers) == 0 and the sentinel is returned; plugin/forward/resolve.go then skips that source and tries the next.","commonSituations":"Forward plugin configured with `forward . /etc/resolv.conf` where /etc/resolv.conf is empty or has all nameserver lines stripped (common in minimal containers or systemd-resolved setups); malformed resolv.conf where nameserver lines are commented or misspelled; Kubernetes pod networking edge cases leaving an empty file.","solutions":["Check the resolv.conf the forward plugin reads and add valid `nameserver` entries.","If /etc/resolv.conf is empty, point the forward directive at an explicit upstream list, e.g. `forward . 8.8.8.8 8.8.4.4`.","For containers, configure the runtime's DNS settings (docker --dns, kubelet resolvConf) so resolv.conf is populated.","Verify nameserver lines are not commented out or misspelled (e.g. `name_server`)."],"exampleFix":"// Corefile\n// before\nforward . /etc/resolv.conf  # empty file -> no servers\n// after\nforward . 8.8.8.8 1.1.1.1","handlingStrategy":"fallback","validationCode":"if st, err := os.Stat(resolvConf); err != nil || st.Size() == 0 {\n    return errors.New(\"resolv.conf missing or empty\")\n}","typeGuard":null,"tryCatchPattern":"servers, parseErr := parse.HostPortOrFile(path)\nif errors.Is(parseErr, parse.ErrNoNameservers) {\n    continue // or fall back to static upstreams\n}","preventionTips":["Ensure resolv.conf has at least one nameserver line","Prefer explicit upstream IPs in the Corefile","Configure container runtime DNS properly"],"tags":["dns","resolv-conf","nameservers","config"],"backgroundTag":"empty-result-set","analyzedSha":"558c9757a92b361e550bdba82d0b4ddf3d12d595","analyzedAt":"2026-09-06T22:47:02.106Z","contentChangedAt":"2026-09-06T22:47:02.106Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}