hashicorp/nomad · error
Defaulting advertise to localhost is unsafe, please set adve
Error message
Defaulting advertise to localhost is unsafe, please set advertise manually
What it means
When falling back to the bind address, if the only IP found is loopback and the agent is not in dev mode, Consul refuses to default advertise to localhost because other nodes could not reach it. This is a deliberate safety error, not a bug.
Source
Thrown at command/agent/config.go:2566
}
// Fallback to bind address first, and then try resolving the local hostname
ips, err := net.LookupIP(bind)
if err != nil {
return "", fmt.Errorf("Error resolving bind address %q: %v", bind, err)
}
// Return the first non-localhost unicast address
for _, ip := range ips {
if ip.IsLinkLocalUnicast() || ip.IsGlobalUnicast() {
return normalizeAddrWithPort(ip.String(), defport), nil
}
if ip.IsLoopback() {
if dev {
// loopback is fine for dev mode
return normalizeAddrWithPort(ip.String(), defport), nil
}
return "", fmt.Errorf("Defaulting advertise to localhost is unsafe, please set advertise manually")
}
}
// Bind is not localhost but not a valid advertise IP, use first private IP
addr, err = listenerutil.ParseSingleIPTemplate("{{ GetPrivateIP }}")
if err != nil {
return "", fmt.Errorf("Unable to parse default advertise address: %v", err)
}
return normalizeAddrWithPort(addr, defport), nil
}
// isMissingPort returns true if an error is a "missing port" error from
// net.SplitHostPort.
func isMissingPort(err error) bool {
// matches error const in net/ipsock.go
const missingPort = "missing port in address"
return err != nil && strings.Contains(err.Error(), missingPort)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set advertise_reconnect_timeout... i.e. set advertise explicitly to the node's routable IP
- Set bind_addr to a non-loopback interface address (e.g. the private IP or 0.0.0.0)
- Use -dev mode only if this is truly a local development agent
- Bring up a non-loopback network interface on the host
Example fix
// before bind_addr = "127.0.0.1" // prod server // after bind_addr = "0.0.0.0" advertise_addr = "10.0.0.5"
Defensive patterns
Strategy: validation
Validate before calling
if !dev && cfg.Advertise == "" {
ip := firstNonLoopbackLocalIP()
if ip == nil {
return errors.New("no non-loopback IP; refusing to start without advertise")
}
} Try / catch
parsed, err := net.ParseIP(candidate)
if err != nil || parsed.IsLoopback() {
return errors.New("advertise must be a non-loopback routable IP")
} Prevention
- Never leave advertise unset outside dev mode
- Verify the host has a non-loopback interface before starting Consul
- Don't reuse dev-mode configs for servers
- Assert at boot that the chosen advertise IP is non-loopback
When it happens
Trigger: advertise unset, bind resolves only to 127.0.0.1/::1 (e.g. bind_addr not set while networking is loopback-only, or bind explicitly "127.0.0.1"), and the agent is started without -dev.
Common situations: Running a server/agent in a container with only the loopback interface up, forgetting bind_addr in production config, or copying a dev-mode config to a real deployment.
Related errors
- Unable to parse default advertise address: %v
- Failed to parse HTTP advertise address (%v, %v, %v, %v): %v
- Failed to parse RPC advertise address: %v
- Failed to parse Serf advertise address: %v
- Error parsing advertise address template: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5b35665d34f9e2b0.
Report an issue: GitHub.