hashicorp/nomad · error

Consul Ingress Service requires a name

Error message

Consul Ingress Service requires a name

What it means

Ingress gateway service entries are pre-validated before being sent to Consul. Consul requires each ingress service entry to have a name, so an empty s.Name fails validation in nomad/structs/services.go.

Source

Thrown at nomad/structs/services.go:2421

	}

	if !pointer.Eq(s.MaxConcurrentRequests, o.MaxConcurrentRequests) {
		return false
	}

	return true
}

func (s *ConsulIngressService) Validate(protocol string) error {
	if s == nil {
		return nil
	}

	// pre-validate service Name and Hosts before passing along to consul:
	// https://developer.hashicorp.com/consul/docs/connect/config-entries/ingress-gateway#services

	if s.Name == "" {
		return errors.New("Consul Ingress Service requires a name")
	}

	switch protocol {
	case "tcp":
		if s.Name == "*" {
			return errors.New(`Consul Ingress Service doesn't support wildcard name for "tcp" protocol`)
		}

		if len(s.Hosts) != 0 {
			return errors.New(`Consul Ingress Service doesn't support associating hosts to a service for the "tcp" protocol`)
		}
	default:
		if s.Name == "*" && len(s.Hosts) != 0 {
			return errors.New(`Consul Ingress Service with a wildcard "*" service name can not also specify hosts`)
		}
	}

	return nil

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set a name on the ingress service entry (a real service name or "*" for a catch-all)
  2. Check Terraform/job templating so the name variable is not rendered empty

Example fix

// before
listener {
  port     = 8080
  protocol = "http"
  services { }
}
// after
listener {
  port     = 8080
  protocol = "http"
  services { name = "web" }
}
Defensive patterns

Strategy: validation

Validate before calling

function validateIngressServiceNames(gateway) {
  for (const l of gateway.listeners ?? []) {
    for (const s of l.services ?? []) {
      if (!s.name) throw new Error(`ingress service on port ${l.port} requires a name`);
    }
  }
}

Type guard

function hasIngressName(s) { return typeof s.name === "string" && s.name.length > 0; }

Try / catch

try {
  await nomad.jobs.validate(job);
} catch (e) {
  if (e.message === "Consul Ingress Service requires a name") {
    console.error("Add a name (or '*') to every ingress service entry");
  } else throw e;
}

Prevention

When it happens

Trigger: Defining a connect { gateway { ingress {} } } listener service with an omitted/empty name and submitting the job for validation.

Common situations: Hand-writing ingress gateway stanzas and forgetting the name field; generating ingress configs programmatically where the name defaults to empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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