hashicorp/nomad · error

Failed to parse Serf address: %v

Error message

Failed to parse Serf address: %v

What it means

Same normalization pass as RPC/HTTP: Addresses.Serf is validated with normalizeBind against BindAddr. A Serf bind address that cannot be parsed (invalid IP or failing template) stops agent startup with this error. The wrapped %v explains the concrete parse problem.

Source

Thrown at command/agent/config.go:2393

		c.BindAddr = ipStr
	}
	c.BindAddr = ipaddr.NormalizeAddr(c.BindAddr)

	httpAddrs, err := normalizeMultipleBind(c.Addresses.HTTP, c.BindAddr)
	if err != nil {
		return fmt.Errorf("Failed to parse HTTP address: %v", err)
	}
	c.Addresses.HTTP = strings.Join(httpAddrs, " ")

	addr, err := normalizeBind(c.Addresses.RPC, c.BindAddr)
	if err != nil {
		return fmt.Errorf("Failed to parse RPC address: %v", err)
	}
	c.Addresses.RPC = addr

	addr, err = normalizeBind(c.Addresses.Serf, c.BindAddr)
	if err != nil {
		return fmt.Errorf("Failed to parse Serf address: %v", err)
	}
	c.Addresses.Serf = addr

	c.normalizedAddrs = &NormalizedAddrs{
		RPC:  normalizeAddrWithPort(c.Addresses.RPC, c.Ports.RPC),
		Serf: normalizeAddrWithPort(c.Addresses.Serf, c.Ports.Serf),
	}
	c.normalizedAddrs.HTTP = make([]string, len(httpAddrs))
	for i, addr := range httpAddrs {
		c.normalizedAddrs.HTTP[i] = normalizeAddrWithPort(addr, c.Ports.HTTP)
	}

	addr, err = normalizeAdvertise(c.AdvertiseAddrs.HTTP, httpAddrs[0], c.Ports.HTTP, c.DevMode)
	if err != nil {
		return fmt.Errorf("Failed to parse HTTP advertise address (%v, %v, %v, %v): %v", c.AdvertiseAddrs.HTTP, c.Addresses.HTTP, c.Ports.HTTP, c.DevMode, err)
	}
	c.AdvertiseAddrs.HTTP = addr

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Correct addresses.serf to a valid IP or fix the template syntax
  2. Confirm the interface name in the template exists on the host
  3. Ensure the value is a bare address without scheme or port
  4. Check the wrapped %v message for the underlying cause

Example fix

// before
addresses { serf = "{{ GetInterfaceIP \"en01\" }}" } # interface typo
// after
addresses { serf = "{{ GetInterfaceIP \"en0\" }}" }
Defensive patterns

Strategy: validation

Validate before calling

func validSerfAddr(v string) bool {
	if v == "" { return true }
	return net.ParseIP(v) != nil || strings.HasPrefix(v, "{{")
}
// plus confirm any templated interface exists: iface, _ := net.InterfaceByName(name)

Prevention

When it happens

Trigger: addresses.serf set to a malformed IP, a template ({{ GetInterfaceIP ... }}) that fails or returns nothing parseable, or an address containing an illegal port/zone component.

Common situations: Typo in interface name inside the template (e.g. eth01); LAN interface absent at boot on VMs/containers so the template resolves empty; stray whitespace or quotes around the value in HCL/JSON.

Understand the failure class

Related errors


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