hashicorp/nomad · error

Consul Ingress Service doesn't support associating hosts to

Error message

Consul Ingress Service doesn't support associating hosts to a service for the "tcp" protocol

What it means

Ingress service entries on a tcp listener cannot declare hosts, because tcp listeners have no HTTP Host header to match against; Consul routes purely by port. Nomad enforces this in validateIngressService before calling Consul.

Source

Thrown at nomad/structs/services.go:2431

	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
}

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

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove the hosts block from the tcp-protocol ingress service entry
  2. Switch the listener protocol to "http" if hostname-based routing via hosts is needed

Example fix

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

Strategy: validation

Validate before calling

function validateTcpHosts(listener) {
  if (listener.protocol === "tcp") {
    for (const s of listener.services ?? []) {
      if ((s.hosts ?? []).length > 0) throw new Error(`ingress service ${s.name}: hosts not allowed for tcp protocol`);
    }
  }
}

Type guard

function tcpHasHosts(s, proto) { return proto === "tcp" && Array.isArray(s.hosts) && s.hosts.length > 0; }

Try / catch

try {
  await nomad.jobs.validate(job);
} catch (e) {
  if (e.message.includes("doesn't support associating hosts")) {
    console.error("Remove hosts from tcp-protocol ingress services");
  } else throw e;
}

Prevention

When it happens

Trigger: An ingress listener with protocol = "tcp" whose service block includes a non-empty hosts list.

Common situations: Reusing an http-mode service entry (with hosts) under a tcp listener; assuming hosts act as allowlists for tcp rather than routing matchers.

Related errors


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