hashicorp/nomad · error
Connect proxy task must not have a service block
Error message
Connect proxy task must not have a service block
What it means
For Consul Connect proxy tasks (task kind is connect-proxy), Task.Validate forbids declaring `service` blocks on the task itself, emitting "Connect proxy task must not have a service block". Proxy services are defined at group level and wired automatically by Connect, so per-task services are invalid.
Source
Thrown at nomad/structs/structs.go:8382
if t.DispatchPayload != nil {
if err := t.DispatchPayload.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Dispatch Payload validation failed: %v", err))
}
}
// Validate the Lifecycle block if there
if t.Lifecycle != nil {
if err := t.Lifecycle.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Lifecycle validation failed: %v", err))
}
}
// Validation for TaskKind field which is used for Consul Connect integration
if t.Kind.IsConnectProxy() {
// This task is a Connect proxy so it should not have service blocks
if len(t.Services) > 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Connect proxy task must not have a service block"))
}
if t.Leader {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Connect proxy task must not have leader set"))
}
// Ensure the proxy task has a corresponding service entry
serviceErr := ValidateConnectProxyService(t.Kind.Value(), tg.Services)
if serviceErr != nil {
mErr.Errors = append(mErr.Errors, serviceErr)
}
}
// Validation for volumes
for idx, vm := range t.VolumeMounts {
if _, ok := tg.Volumes[vm.Volume]; !ok {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Volume Mount (%d) references undefined volume %s", idx, vm.Volume))
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Remove the service blocks from the connect-proxy task
- Declare the proxy service via the group's `connect { sidecar_service { proxy {} } }` stanza instead
- Let Nomad generate the proxy task rather than writing kind="connect-proxy" manually
Example fix
// before
task "mesh-proxy" {
kind = "connect-proxy:api"
service {
name = "api"
}
}
// after
group "api" {
connect {
sidecar_service {
proxy {}
}
}
} Defensive patterns
Strategy: validation
Validate before calling
if task.Kind.IsConnectProxy() && len(task.Services) > 0 {
return fmt.Errorf("connect proxy task %q must not declare services", task.Name)
} Type guard
func isConnectProxy(t *structs.Task) bool { return t.Kind.IsConnectProxy() } Try / catch
if err := job.Validate(); err != nil {
if strings.Contains(err.Error(), "must not have a service block") { /* move services to group/connect */ }
} Prevention
- Never hand-write kind="connect-proxy" tasks; use sidecar_service
- Keep service blocks at group level for Connect workloads
- Validate connect jobs in CI
When it happens
Trigger: Defining a task with `kind = "connect-proxy:..."` (or generated proxy tasks) while also listing `service` blocks inside that task.
Common situations: Hand-crafting connect proxy tasks instead of using `connect { sidecar_service {} }`; copying a normal task spec and adding the connect-proxy kind; generated jobs from older tooling.
Related errors
- Service with provider nomad cannot include Connect blocks
- Connect proxy task must not have leader set
- timed out waiting for socket proxy to exit
- consul address must be set on nomad client
- error creating bootstrap configuration for Connect proxy sid
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/29c4084b175bb260.
Report an issue: GitHub.