hashicorp/nomad · error
invalid IP address %q
Error message
invalid IP address %q
What it means
After splitting an extra_hosts entry on the first colon, GenerateEtcHostsMount validates the second part with net.ParseIP. This error means the entry had a colon but the right-hand side is not a valid IPv4/IPv6 address literal.
Source
Thrown at drivers/shared/hostnames/mount.go:54
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
# this entry is the IP address and hostname of the allocation
# shared with tasks in the task group's network
%s %s
`, hostsCfg.Address, hostsCfg.Hostname)
if len(extraHosts) > 0 {
content.WriteString("\n# these entries are extra hosts added by the task config")
for _, hostLine := range extraHosts {
hostsEntry := strings.SplitN(hostLine, ":", 2)
if len(hostsEntry) != 2 {
return nil, fmt.Errorf("invalid hosts entry %q", hostLine)
}
if net.ParseIP(hostsEntry[1]) == nil {
return nil, fmt.Errorf("invalid IP address %q", hostLine)
}
content.WriteString(fmt.Sprintf("\n%s %s", hostsEntry[1], hostsEntry[0]))
}
content.WriteString("\n")
}
path := filepath.Join(taskDir, "hosts")
// tasks within an alloc should be able to share and modify the file, so
// only write to it if it doesn't exist
if _, err := os.Stat(path); os.IsNotExist(err) {
err := os.WriteFile(path, []byte(content.String()), 0644)
if err != nil {
return nil, err
}
}
// Note that we're not setting readonly. The file is in the task dirView on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the format is "hostname:valid-IP" — the value after the colon must parse as an IP (e.g. "web:10.0.0.5")
- Swap the fields if you wrote the IP first
- Use a resolvable IP, not a DNS name — extra_hosts only accepts literal addresses
- Check IPv6 entries parse with net.ParseIP (use full/compressed valid forms, no zone IDs)
Example fix
// before extra_hosts = ["10.0.0.5:myhost"] // after extra_hosts = ["myhost:10.0.0.5"]
Defensive patterns
Strategy: validation
Validate before calling
func validExtraHostIPs(hosts []string) error {
for _, h := range hosts {
parts := strings.SplitN(h, ":", 2)
if len(parts) == 2 && net.ParseIP(parts[1]) == nil {
return fmt.Errorf("extra host %q: %q is not a valid IP", h, parts[1])
}
}
return nil
} Prevention
- Remember the order is hostname:IP, not IP:hostname
- Only literal IPv4/IPv6 addresses are accepted — never DNS names
- Check IPv6 entries with net.ParseIP locally before submitting the job
When it happens
Trigger: extra_hosts entry like "myhost:not-an-ip", "myhost:192.168.1", "myhost:example.com" (hostnames on the wrong side), or a reversed "IP:hostname" pair, reaching GenerateEtcHostsMount via createContainerConfig.
Common situations: Swapping the mapping order (Docker uses hostname:IP but users write IP:hostname); truncated IPs from variable substitution; IPv6 zones or shorthand net.ParseIP rejects (e.g. missing brackets or bad compression); using DNS names instead of IPs.
Related errors
- invalid hosts entry %q
- host path must be set in configuration for devices
- invalid value for cpu_cfs_period
- failed to build mount for /etc/hosts: %v
- failed to parse security_opt configuration: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/8d14c3e6a69abb45.
Report an issue: GitHub.