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

  1. Set advertise_reconnect_timeout... i.e. set advertise explicitly to the node's routable IP
  2. Set bind_addr to a non-loopback interface address (e.g. the private IP or 0.0.0.0)
  3. Use -dev mode only if this is truly a local development agent
  4. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/5b35665d34f9e2b0. Report an issue: GitHub.