hashicorp/nomad · error

error parsing address %q: %v

Error message

error parsing address %q: %v

What it means

parseAddress splits a raw address string into host and port using net.SplitHostPort. If the string fails to split for any reason other than 'missing port in address' (e.g. too many colons, unbalanced brackets), the underlying error is wrapped and returned, blocking service address registration.

Source

Thrown at command/agent/consul/service_client.go:2167

//
// If the managed service of the specified id does not exist, or the service does
// not have a sidecar proxy, nil is returned.
func getNomadSidecar(id string, services map[string]*api.AgentService) *api.AgentService {
	if _, exists := services[id]; !exists {
		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

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Wrap IPv6 literals in brackets: [fd00::1]:8080.
  2. Remove any scheme prefix (http://) from the address field.
  3. Provide host and port separately (address + port fields) instead of a combined string.
  4. Quote/escape the address in config so interpolation doesn't inject extra colons.

Example fix

// before
advertise { http = "fd00::1:4646" }
// after
advertise { http = "[fd00::1]:4646" }
Defensive patterns

Strategy: validation

Validate before calling

func validAddr(s string) bool {
  if _, _, err := net.SplitHostPort(s); err != nil {
    return strings.Contains(err.Error(), "missing port in address") && net.ParseIP(s) != nil
  }
  return true
}

Type guard

func isBracketedIPv6(s string) bool {
  return strings.HasPrefix(s, "[") && strings.Contains(s, "]")
}

Try / catch

addr, err := parseAddress(raw, port)
if err != nil {
  return fmt.Errorf("invalid service address %q: %w", raw, err)
}

Prevention

When it happens

Trigger: Passing an address with multiple colons without IPv6 brackets (e.g. "::1:8080" or "fd00::1:80"), or an empty/quoted malformed string, into the address parsing used when building service registrations.

Common situations: Advertise address templating producing IPv6 literals without brackets; env var interpolation yielding garbage; copy-pasted address containing scheme like "http://host:8080".

Related errors


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