hashicorp/nomad · error

Consul Ingress Service with a wildcard "*" service name can

Error message

Consul Ingress Service with a wildcard "*" service name can not also specify hosts

What it means

For non-tcp (e.g. http) ingress protocols, Consul allows the wildcard name "*" OR explicit hosts, but not both: a wildcard catch-all cannot simultaneously be constrained to specific hosts. Nomad validates this combination in validateIngressService.

Source

Thrown at nomad/structs/services.go:2435

	// 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
}

// ConsulIngressListener is used to configure a listener on a Consul Ingress
// Gateway.
type ConsulIngressListener struct {
	Port     int
	Protocol string
	Services []*ConsulIngressService
}

func (l *ConsulIngressListener) Copy() *ConsulIngressListener {
	if l == nil {
		return nil
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set an explicit service name if hosts are required
  2. Keep name = "*" and remove the hosts block
  3. Split into multiple service entries: one wildcard, one per named service with hosts

Example fix

// before
services {
  name  = "*"
  hosts = ["app.example.com"]
}
// after
services {
  name  = "app"
  hosts = ["app.example.com"]
}
Defensive patterns

Strategy: validation

Validate before calling

function validateWildcardWithHosts(s) {
  if (s.name === "*" && (s.hosts ?? []).length > 0) {
    throw new Error("wildcard '*' ingress service cannot also specify hosts");
  }
}

Type guard

function isWildcardWithHosts(s) { return s.name === "*" && Array.isArray(s.hosts) && s.hosts.length > 0; }

Try / catch

try {
  await nomad.jobs.validate(job);
} catch (e) {
  if (e.message.includes("can not also specify hosts")) {
    console.error("Split the wildcard entry from host-specific entries");
  } else throw e;
}

Prevention

When it happens

Trigger: An ingress service entry with name = "*" and a non-empty hosts list on a listener whose protocol is not "tcp".

Common situations: Trying to define a default catch-all route plus host overrides in one entry; template merging producing name="*" while preserving hosts.

Related errors


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