hashicorp/nomad · error

Consul Ingress Service doesn't support wildcard name for "tc

Error message

Consul Ingress Service doesn't support wildcard name for "tcp" protocol

What it means

For tcp-protocol ingress listeners, Consul does not allow the wildcard service name "*" (wildcards only make sense for http/protocol-aware routing). Nomad mirrors this constraint in its pre-validation at nomad/structs/services.go:2427.

Source

Thrown at nomad/structs/services.go:2427

	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
}

// ConsulIngressListener is used to configure a listener on a Consul Ingress
// Gateway.
type ConsulIngressListener struct {
	Port     int

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Replace name = "*" with the explicit service name the tcp listener routes to
  2. Change the listener protocol to "http" if wildcard routing semantics are wanted

Example fix

// before
listener {
  port     = 9090
  protocol = "tcp"
  services { name = "*" }
}
// after
listener {
  port     = 9090
  protocol = "tcp"
  services { name = "tcp-app" }
}
Defensive patterns

Strategy: validation

Validate before calling

function validateTcpWildcard(listener) {
  if (listener.protocol === "tcp") {
    for (const s of listener.services ?? []) {
      if (s.name === "*") throw new Error("tcp ingress listeners cannot use wildcard name '*'");
    }
  }
}

Type guard

function isWildcardTcp(s, proto) { return proto === "tcp" && s.name === "*"; }

Try / catch

try {
  await nomad.jobs.validate(job);
} catch (e) {
  if (e.message.includes("doesn't support wildcard name")) {
    console.error("Use an explicit service name for tcp listeners");
  } else throw e;
}

Prevention

When it happens

Trigger: An ingress gateway listener with protocol = "tcp" whose service entry has name = "*".

Common situations: Copy-pasting an http listener with wildcard catch-all into a tcp listener; attempting a default-catch-all TCP route.

Related errors


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