hashicorp/nomad · error
Check %s invalid: tcp checks are not valid for Connect enabl
Error message
Check %s invalid: tcp checks are not valid for Connect enabled services
What it means
This error is raised in validateConsulService when a TCP check is attached to a Consul Connect-enabled service (service has a connect stanza with a sidecar_service). TCP checks hit the service's loopback-bound address inside the network namespace and cannot work, so Nomad rejects the configuration up front.
Source
Thrown at nomad/structs/services.go:865
return nil
}
// validateConsulService performs validation on a service which is using the
// consul provider.
func (s *Service) validateConsulService(mErr *multierror.Error) {
// check checks
for _, c := range s.Checks {
// validate the check port
if err := s.validateCheckPort(c); err != nil {
mErr.Errors = append(mErr.Errors, err)
continue
}
// TCP checks against a Consul Connect enabled service are not supported
// due to the service being bound to the loopback interface inside the
// network namespace
if c.Type == ServiceCheckTCP && s.Connect != nil && s.Connect.SidecarService != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Check %s invalid: tcp checks are not valid for Connect enabled services", c.Name))
continue
}
// validate the consul check
if err := c.validateConsul(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Check %s invalid: %v", c.Name, err))
}
}
// validate the consul service kind
switch api.ServiceKind(s.Kind) {
case api.ServiceKindTypical,
api.ServiceKindAPIGateway,
api.ServiceKindIngressGateway,
api.ServiceKindMeshGateway,
api.ServiceKindTerminatingGateway:
default:
mErr.Errors = append(mErr.Errors, fmt.Errorf("Service %s kind must be one of consul service kind or empty", s.Name))View on GitHub (pinned to 482b49bf1a)
Solutions
- Change the check type to "http" or "grpc" targeting the sidecar proxy (e.g. address_mode = "driver", port pointing at the proxy port).
- Remove the TCP check and rely on Consul's mesh health or an application-level HTTP check.
- Drop the connect stanza if Connect is not actually needed.
Example fix
// before
service {
name = "web"
connect { sidecar_service {} }
check { type = "tcp" interval = "10s" timeout = "2s" }
}
// after
service {
name = "web"
connect { sidecar_service {} }
check {
type = "http"
path = "/health"
port = "9090"
interval = "10s"
timeout = "2s"
}
} Defensive patterns
Strategy: validation
Validate before calling
func validateConnectChecks(svc Service) error {
if svc.Connect != nil && svc.Connect.SidecarService != nil {
for _, c := range svc.Checks {
if c.Type == "tcp" {
return fmt.Errorf("check %q: tcp not allowed on Connect-enabled services", c.Name)
}
}
}
return nil
} Prevention
- Use http or grpc checks against the sidecar proxy port for Connect services
- Document that TCP checks are incompatible with Connect in your job templates
- Review checks whenever migrating a service to Connect
When it happens
Trigger: A service stanza with `connect { sidecar_service {} }` and a check of type = "tcp".
Common situations: Adding a standard TCP health check to a service that was later converted to use Consul Connect; migrating a plain service to Connect and keeping existing checks.
Related errors
- expose may only be set for Consul service checks
- on_update may only be set to ignore_warnings for Consul serv
- success_before_passing may only be set for Consul service ch
- failures_before_critical may only be set for Consul service
- failures_before_warning may only be set for Consul service c
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c261eab743519474.
Report an issue: GitHub.