{"record":{"id":"d7d65cb3398642fa","repo":"hashicorp/nomad","slug":"consul-ingress-service-doesn-t-support-wildcard-na","errorCode":null,"errorMessage":"Consul Ingress Service doesn't support wildcard name for \"tcp\" protocol","messagePattern":"Consul Ingress Service doesn't support wildcard name for \"tcp\" protocol","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/services.go","lineNumber":2427,"sourceCode":"\treturn true\n}\n\nfunc (s *ConsulIngressService) Validate(protocol string) error {\n\tif s == nil {\n\t\treturn nil\n\t}\n\n\t// pre-validate service Name and Hosts before passing along to consul:\n\t// https://developer.hashicorp.com/consul/docs/connect/config-entries/ingress-gateway#services\n\n\tif s.Name == \"\" {\n\t\treturn errors.New(\"Consul Ingress Service requires a name\")\n\t}\n\n\tswitch protocol {\n\tcase \"tcp\":\n\t\tif s.Name == \"*\" {\n\t\t\treturn errors.New(`Consul Ingress Service doesn't support wildcard name for \"tcp\" protocol`)\n\t\t}\n\n\t\tif len(s.Hosts) != 0 {\n\t\t\treturn errors.New(`Consul Ingress Service doesn't support associating hosts to a service for the \"tcp\" protocol`)\n\t\t}\n\tdefault:\n\t\tif s.Name == \"*\" && len(s.Hosts) != 0 {\n\t\t\treturn errors.New(`Consul Ingress Service with a wildcard \"*\" service name can not also specify hosts`)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ConsulIngressListener is used to configure a listener on a Consul Ingress\n// Gateway.\ntype ConsulIngressListener struct {\n\tPort     int","sourceCodeStart":2409,"sourceCodeEnd":2445,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/services.go#L2409-L2445","documentation":"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.","triggerScenarios":"An ingress gateway listener with protocol = \"tcp\" whose service entry has name = \"*\".","commonSituations":"Copy-pasting an http listener with wildcard catch-all into a tcp listener; attempting a default-catch-all TCP route.","solutions":["Replace name = \"*\" with the explicit service name the tcp listener routes to","Change the listener protocol to \"http\" if wildcard routing semantics are wanted"],"exampleFix":"// before\nlistener {\n  port     = 9090\n  protocol = \"tcp\"\n  services { name = \"*\" }\n}\n// after\nlistener {\n  port     = 9090\n  protocol = \"tcp\"\n  services { name = \"tcp-app\" }\n}","handlingStrategy":"validation","validationCode":"function validateTcpWildcard(listener) {\n  if (listener.protocol === \"tcp\") {\n    for (const s of listener.services ?? []) {\n      if (s.name === \"*\") throw new Error(\"tcp ingress listeners cannot use wildcard name '*'\");\n    }\n  }\n}","typeGuard":"function isWildcardTcp(s, proto) { return proto === \"tcp\" && s.name === \"*\"; }","tryCatchPattern":"try {\n  await nomad.jobs.validate(job);\n} catch (e) {\n  if (e.message.includes(\"doesn't support wildcard name\")) {\n    console.error(\"Use an explicit service name for tcp listeners\");\n  } else throw e;\n}","preventionTips":["Never template name = \"*\" into tcp listeners","Reserve wildcards for http protocol listeners only","Review ingress configs when converting http listeners to tcp"],"tags":["nomad","consul","ingress-gateway","tcp","wildcard"],"backgroundTag":"invalid-config-combination","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}