hashicorp/nomad · critical

Client RPC advertise address is not a TCP Address: %v

Error message

Client RPC advertise address is not a TCP Address: %v

What it means

During RPC listener setup, the server binds a client RPC listener and then verifies its advertised address is a usable *net.TCPAddr. If the type assertion fails (advertise address is not a concrete TCP address, e.g. unspecified or mis-derived), the listener is closed and NewServer fails with this error.

Source

Thrown at nomad/server.go:1228

	s.setupStreamingEndpoints(s.rpcServer)

	listener, err := s.createRPCListener()
	if err != nil {
		listener.Close()
		return err
	}

	if s.config.ClientRPCAdvertise != nil {
		s.clientRpcAdvertise = s.config.ClientRPCAdvertise
	} else {
		s.clientRpcAdvertise = s.rpcListener.Addr()
	}

	// Verify that we have a usable advertise address
	clientAddr, ok := s.clientRpcAdvertise.(*net.TCPAddr)
	if !ok {
		listener.Close()
		return fmt.Errorf("Client RPC advertise address is not a TCP Address: %v", clientAddr)
	}
	if clientAddr.IP.IsUnspecified() {
		listener.Close()
		return fmt.Errorf("Client RPC advertise address is not advertisable: %v", clientAddr)
	}

	if s.config.ServerRPCAdvertise != nil {
		s.serverRpcAdvertise = s.config.ServerRPCAdvertise
	} else {
		// Default to the Serf Advertise + RPC Port
		serfIP := s.config.SerfConfig.MemberlistConfig.AdvertiseAddr
		if serfIP == "" {
			serfIP = s.config.SerfConfig.MemberlistConfig.BindAddr
		}

		addr := net.JoinHostPort(serfIP, fmt.Sprintf("%d", clientAddr.Port))
		resolved, err := net.ResolveTCPAddr("tcp", addr)
		if err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set an explicit, resolvable IP in bind_addr / advertise blocks (e.g. 10.0.0.5) instead of a hostname or wildcard.
  2. Ensure the configured interface exists before the agent starts (network readiness ordering).
  3. Check the resolved advertise address with `nomad node status` / agent logs and fix the config accordingly.

Example fix

// before
bind_addr = "my-host-internal"   // unresolved hostname
// after
bind_addr = "192.168.1.10"       // concrete, routable IP
Defensive patterns

Strategy: validation

Validate before calling

ip := net.ParseIP(cfg.BindAddr)
if ip == nil || ip.IsUnspecified() {
    return fmt.Errorf("bind_addr %q must resolve to a concrete, routable IP", cfg.BindAddr)
}

Type guard

func isTCPAddr(a net.Addr) (*net.TCPAddr, bool) {
    t, ok := a.(*net.TCPAddr)
    return t, ok && !t.IP.IsUnspecified()
}

Try / catch

srv, err := nomad.NewServer(cfg, logger)
if err != nil && strings.Contains(err.Error(), "not a TCP Address") {
    return fmt.Errorf("fix bind/advertise address config: %w", err)
}

Prevention

When it happens

Trigger: NewServer where bind/advertise configuration resolves clientRpcAdvertise to something other than *net.TCPAddr — typically an address that couldn't be resolved to a concrete IP, or advertise configured to a hostname that yields an unusable value.

Common situations: bind_addr set to a hostname that doesn't resolve, advertise settings pointing at 0.0.0.0-style values, misconfigured NAT/advertise stanzas, or containers started before their network interface is available.

Related errors


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