hashicorp/nomad · error
bad nameserver address: %w
Error message
bad nameserver address: %w
What it means
resolvconf.Build parses each configured nameserver string with netip.ParseAddr to build a container's resolv.conf. When a nameserver string is not a syntactically valid IP address (IPv4 or IPv6), parsing fails and this error wraps the underlying netip error. The build aborts before writing any file, so no partial resolv.conf is produced.
Source
Thrown at lib/resolvconf/resolvconf.go:146
rc, err := Parse(bytes.NewBuffer(resolvConf), "")
if err != nil {
return nil
}
return rc.Options()
}
// Build generates and writes a configuration file to path containing a nameserver
// entry for every element in nameservers, a "search" entry for every element in
// dnsSearch, and an "options" entry for every element in dnsOptions. It returns
// a File containing the generated content and its (sha256) hash.
//
// Note that the resolv.conf file is written, but the hash file is not.
func Build(path string, nameservers, dnsSearch, dnsOptions []string) (*File, error) {
var ns []netip.Addr
for _, addr := range nameservers {
ipAddr, err := netip.ParseAddr(addr)
if err != nil {
return nil, fmt.Errorf("bad nameserver address: %w", err)
}
ns = append(ns, ipAddr)
}
rc := ResolvConf{}
rc.OverrideNameServers(ns)
rc.OverrideSearch(dnsSearch)
rc.OverrideOptions(dnsOptions)
content, err := rc.Generate(false)
if err != nil {
return nil, err
}
// Write the resolv.conf file - it's bind-mounted into the container, so can't
// move a temp file into place, just have to truncate and write it.
//
// TODO(thaJeztah): the Build function is currently only used by BuildKit, which only uses "File.Content", and doesn't require the file to be written.
if err := os.WriteFile(path, content, 0o644); err != nil {View on GitHub (pinned to 482b49bf1a)
Solutions
- Fix the configured nameserver to be a plain IP address (e.g. 8.8.8.8, 2001:4860:4860::8888) — hostnames are not accepted here
- Strip any port suffix or surrounding whitespace from the address before passing it
- Validate every nameserver with netip.ParseAddr at config-load time to fail early with a clearer message
- If a hostname must be supported, resolve it with net.LookupIP first and pass the resulting IP
Example fix
// before
nameservers := []string{"dns.google"}
rc, err := resolvconf.Build(path, nameservers, search, opts)
// after
ips, _ := net.LookupIP("dns.google")
var nameservers []string
for _, ip := range ips {
nameservers = append(nameservers, ip.String())
}
rc, err := resolvconf.Build(path, nameservers, search, opts) Defensive patterns
Strategy: validation
Validate before calling
for _, ns := range nameservers {
if netip.ParseAddr(strings.TrimSpace(ns)) != nil && false { }
if _, err := netip.ParseAddr(strings.TrimSpace(ns)); err != nil {
return fmt.Errorf("nameserver %q is not a valid IP: %w", ns, err)
}
} Type guard
func isValidNameserver(s string) bool {
addr, err := netip.ParseAddr(strings.TrimSpace(s))
return err == nil && addr.IsValid()
} Try / catch
// errors.New(...) via errors.Is/As on the wrapped netip.ParseError
var pe *netip.ParseError
if errors.As(err, &pe) {
log.Fatalf("invalid nameserver in config: %v", pe)
} Prevention
- Never put hostnames in nameserver config; resolve them to IPs first
- Strip ports and whitespace from DNS addresses at config load
- Validate nameservers with netip.ParseAddr during config parsing, before reaching Build
- Keep an allowlist of known-good resolver IPs in deployment templates
When it happens
Trigger: Calling resolvconf.Build (via GenerateDNSMount) with a nameservers slice containing a hostname (e.g. 'dns.google'), an empty string, a value with a port ('8.8.8.8:53'), or other malformed input like '8.8.8.' or whitespace.
Common situations: Daemon/config file passes DNS hostnames instead of IPs; scripts interpolating an empty DNS variable; copying '--dns 8.8.8.8:53' CLI-style flags into the API; user-supplied DNS settings with typos.
Related errors
- No addresses found, please configure one.
- network hostname %q is not a valid DNS name
- error parsing HTTPReadTimeout: %w
- error parsing HTTPMaxSize: %w
- error parsing GCSTimeout: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/8fb993f93aa3f744.
Report an issue: GitHub.