hashicorp/nomad · error
error parsing address %q: not an IP address
Error message
error parsing address %q: not an IP address
What it means
When SplitHostPort reports 'missing port in address', parseAddress treats the whole input as the host — but only if net.ParseIP can parse it. A non-IP string with no port (e.g. a bare hostname like 'consul.service.dc1') is rejected because Consul service addresses here must be IP literals.
Source
Thrown at command/agent/consul/service_client.go:2172
return nil
}
sidecarID := id + sidecarSuffix
return services[sidecarID]
}
func parseAddress(raw string, port int) (api.ServiceAddress, error) {
result := api.ServiceAddress{}
addr, portStr, err := net.SplitHostPort(raw)
// Error message from Go's net/ipsock.go
if err != nil {
if !strings.Contains(err.Error(), "missing port in address") {
return result, fmt.Errorf("error parsing address %q: %v", raw, err)
}
// Use the whole input as the address if there wasn't a port.
if ip := net.ParseIP(raw); ip == nil {
return result, fmt.Errorf("error parsing address %q: not an IP address", raw)
}
addr = raw
}
if portStr != "" {
port, err = strconv.Atoi(portStr)
if err != nil {
return result, fmt.Errorf("error parsing port %q: %v", portStr, err)
}
}
result.Address = addr
result.Port = port
return result, nil
}
// morph the tagged_addresses map into the structure consul api wants
func parseTaggedAddresses(m map[string]string, port int) (map[string]api.ServiceAddress, error) {View on GitHub (pinned to 482b49bf1a)
Solutions
- Use an IP literal for the address field, or include a port so SplitHostPort succeeds and the IP check path is bypassed appropriately.
- Resolve the hostname to an IP before configuring (or let address_mode="host" use the interface address).
- If a hostname is intended, use the correct Nomad field that accepts hostnames instead of this IP-only parser path.
Example fix
// before
service { address = "web.service.consul" }
// after
service { address = "10.0.4.12", port = 8080 } Defensive patterns
Strategy: validation
Validate before calling
func ensureIPOrIPPort(raw string) error {
host, port, err := net.SplitHostPort(raw)
if err != nil {
if net.ParseIP(raw) == nil {
return fmt.Errorf("%q is neither an IP nor host:port", raw)
}
return nil
}
_ = host
if _, err := strconv.Atoi(port); err != nil {
return fmt.Errorf("port %q in %q is not numeric", port, raw)
}
return nil
} Type guard
func isIPLiteral(s string) bool { return net.ParseIP(s) != nil } Try / catch
sa, err := parseAddress(raw, port)
if err != nil {
if strings.Contains(err.Error(), "not an IP address") {
ip, lookupErr := net.LookupHost(raw)
if lookupErr == nil { raw = ip[0] }
}
} Prevention
- Resolve hostnames to IPs before assigning Nomad address fields that require IPs.
- Use address_mode="host" to let Nomad pick the interface IP automatically.
- Validate advertised addresses with net.ParseIP at config load time.
- Avoid DNS names in service address fields.
When it happens
Trigger: Calling the service registration path with an address string that is a DNS hostname or arbitrary text with no port, where an IP:port or IP is expected (e.g. service address fields fed from templating).
Common situations: Using consul service DNS names instead of IPs in address fields; template variables that resolve to hostnames; typos leaving the address empty of a port and not an IP.
Related errors
- <combined HCL diagnostics from str.String()>
- error parsing address %q: %v
- error parsing port %q: %v
- Invalid key value pair for topic, topic: %s
- could not parse value as bytes: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1fe10aa4cadc061d.
Report an issue: GitHub.