hashicorp/nomad · error

Bind address resolution failed: %v

Error message

Bind address resolution failed: %v

What it means

During address normalization the agent parses the configured BindAddr as a single-IP template (supporting go-sockaddr templates like {{ GetPrivateIP }}). If ParseSingleIPTemplate fails — the value is not an IP and the template does not resolve to exactly one IP — this error wraps the cause.

Source

Thrown at command/agent/config.go:2373

	nc.HTTPAPIResponseHeaders = maps.Clone(c.HTTPAPIResponseHeaders)
	nc.Sentinel = c.Sentinel.Copy()
	nc.Autopilot = c.Autopilot.Copy()
	nc.Plugins = helper.CopySlice(c.Plugins)
	nc.Limits = c.Limits.Copy()
	nc.Audit = c.Audit.Copy()
	nc.Reporting = c.Reporting.Copy()
	nc.KEKProviders = helper.CopySlice(c.KEKProviders)
	nc.ExtraKeysHCL = slices.Clone(c.ExtraKeysHCL)
	return &nc
}

// normalizeAddrs normalizes Addresses and AdvertiseAddrs to always be
// initialized and have reasonable defaults.
func (c *Config) normalizeAddrs() error {
	if c.BindAddr != "" {
		ipStr, err := listenerutil.ParseSingleIPTemplate(c.BindAddr)
		if err != nil {
			return fmt.Errorf("Bind address resolution failed: %v", err)
		}
		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)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set bind_addr to a literal IP (e.g. 0.0.0.0, or the host's private IP).
  2. If using a go-sockaddr template, verify it resolves to exactly one IP and test with `nomad agent -config ... -verify-only`.
  3. Fix typos and check the wrapped error for the parse failure detail.

Example fix

# before
bind_addr = "my-host.example.com"
# after
bind_addr = "192.168.1.10"        # literal IP
# or a valid single-IP template
bind_addr = "{{ GetPrivateIP }}"
Defensive patterns

Strategy: validation

Validate before calling

if net.ParseIP(cfg.BindAddr) == nil && !strings.Contains(cfg.BindAddr, "{{") {
  return fmt.Errorf("bind_addr %q must be an IP or sockaddr template", cfg.BindAddr)
}

Try / catch

ipStr, err := listenerutil.ParseSingleIPTemplate(bindAddr)
if err != nil {
  return fmt.Errorf("invalid bind_addr %q: %w", bindAddr, err)
}

Prevention

When it happens

Trigger: Config sets bind_addr to a hostname, an invalid IP literal, or a template that evaluates to multiple/zero IPs; normalizeAddrs() runs at config parse time.

Common situations: Setting bind_addr = "localhost" or a DNS name instead of an IP; typos like "0.0.0.0.0"; go-sockaddr template syntax errors; using a template on a host with no matching interface.

Related errors


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