hashicorp/nomad · error

%s checks require an address

Error message

%s checks require an address

What it means

When converting a Nomad service check definition into a Consul agent check registration, HTTP/TCP-style checks need a concrete address:port target. If the check requires a port but the resolved service address has port 0 (no address), registration cannot proceed and Nomad refuses to build the check.

Source

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

// Script checks simply have a TTL set and the caller is responsible for
// running the script and heart-beating.
func createCheckReg(serviceID, checkID string, check *structs.ServiceCheck, host string, port int, namespace string) (*api.AgentCheckRegistration, error) {
	chkReg := api.AgentCheckRegistration{
		ID:        checkID,
		Name:      check.Name,
		ServiceID: serviceID,
		Namespace: normalizeNamespace(namespace),
	}
	chkReg.Status = check.InitialStatus
	chkReg.Timeout = check.Timeout.String()
	chkReg.Interval = check.Interval.String()
	chkReg.SuccessBeforePassing = check.SuccessBeforePassing
	chkReg.FailuresBeforeCritical = check.FailuresBeforeCritical
	chkReg.FailuresBeforeWarning = check.FailuresBeforeWarning

	// Require an address for http or tcp checks
	if port == 0 && check.RequiresPort() {
		return nil, fmt.Errorf("%s checks require an address", check.Type)
	}

	switch check.Type {
	case structs.ServiceCheckHTTP:
		proto := check.Protocol
		if proto == "" {
			proto = "http"
		}
		if check.TLSSkipVerify {
			chkReg.TLSSkipVerify = true
		}
		chkReg.TLSServerName = check.TLSServerName
		base := url.URL{
			Scheme: proto,
			Host:   net.JoinHostPort(host, strconv.Itoa(port)),
		}
		relative, err := url.Parse(check.Path)
		if err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a port or port label to the service stanza so the check has a target address.
  2. Set the check's address/port explicitly via check block port or address_mode="host" with a host port.
  3. If the check is script-based, switch its type so it does not require a port.

Example fix

// before
service { name = "web" check { type = "http", path = "/health" } }
// after
service { name = "web", port = "http"
  check { type = "http", path = "/health", interval = "10s", timeout = "2s" } }
Defensive patterns

Strategy: validation

Validate before calling

// hcl pre-check
// a check with type http|tcp|grpc must have a resolvable port
service {
  name = "web"
  port = "http"          # must resolve to > 0
  check { type = "http", path = "/health", interval = "10s", timeout = "2s" }
}
# validate with: nomad job validate job.nomad.hcl

Type guard

func checkHasPort(svc api.ServiceCheck) bool {
  return !svc.RequiresPort() || svc.PortLabel != ""
}

Try / catch

try {
  nomad.jobRegister(job)
} catch err {
  if strings.Contains(err.Error(), "require an address") {
    log.Error("check missing port label", "service", err)
  }
}

Prevention

When it happens

Trigger: Registering a service check of type http, tcp, or grpc (check.RequiresPort() true) where the check block has neither a port_label nor address_mode-resolvable port, so port == 0 when building the api.AgentServiceCheck.

Common situations: Service stanza declares a check but no port in the service block; address_mode="driver" with a task driver that exposes no ports; typo in port label so no port resolves.

Related errors


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