hashicorp/nomad · error · ErrCgroupMustBeSet
error setting up exec subcommand: %w
Error message
error setting up exec subcommand: %w
What it means
setSubCmdCgroup builds the cgroup-joining cleanup hook for the exec subcommand. When the cgroup path is empty (nothing to join) it fails fast with ErrCgroupMustBeSet wrapped by this message, because without a cgroup the executor cannot contain the spawned process.
Source
Thrown at drivers/shared/executor/executor_universal_linux.go:37
"github.com/hashicorp/nomad/plugins/drivers"
"github.com/opencontainers/cgroups"
"golang.org/x/sys/unix"
)
// setSubCmdCgroup sets the cgroup for non-Task child processes of the
// executor.Executor (since in cg2 it lives outside the task's cgroup)
func (e *UniversalExecutor) setSubCmdCgroup(cmd *exec.Cmd, cgroup string) (func(), error) {
// no extra setup needed for cg v1 or when cgroups are "off"
switch cgroupslib.GetMode() {
case cgroupslib.OFF, cgroupslib.CG1:
return func() {}, nil
default:
// continue for cg v2
}
if cgroup == "" {
return nil, fmt.Errorf("error setting up exec subcommand: %w", ErrCgroupMustBeSet)
}
fd, cleanup, err := e.statCG(cgroup)
if err != nil {
return nil, err
}
// make sure attrs struct has been set
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = new(syscall.SysProcAttr)
}
cmd.SysProcAttr.UseCgroupFD = true
cmd.SysProcAttr.CgroupFD = fd
return cleanup, nil
}
func (e *UniversalExecutor) ListProcesses() set.Collection[procstats.ProcessID] {View on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the driver sets the cgroup path (driver config / client cgroup settings) before exec
- Verify client cgroup configuration (nomad client config, cgroup v1 vs v2) matches the host
- Check earlier cgroup creation logs for silent failures leaving path empty
- Upgrade/align Nomad client and driver plugin versions so cgroup setup contract is consistent
Example fix
// before (driver plugin)
execCmd := &ExecCommand{} // cgroup never set
// after
execCmd.Cgroup = cgroupsPath // computed from alloc/task ID Defensive patterns
Strategy: validation
Validate before calling
if cgroupPath == "" {
return fmt.Errorf("refusing to exec: cgroup path must be configured")
} Try / catch
if err != nil && strings.Contains(err.Error(), "ErrCgroupMustBeSet") || strings.Contains(err.Error(), "setting up exec subcommand") {
// cgroup was never set; fix driver config before retry
return fmt.Errorf("cgroup setup missing: %w", err)
} Prevention
- Ensure drivers always populate the cgroup path in ExecCommand
- Align client cgroup v1/v2 configuration with driver expectations
- Log cgroup path at task launch to catch empty values early
When it happens
Trigger: setSubCmdCgroup is invoked on UniversalExecutor/other executors before launching a subcommand; if e.command's configured cgroup is "" after switch-handling cg versions, this error is returned.
Common situations: Driver did not configure cgroup path (e.g. TaskConfig cgroups settings dropped); running in an environment where cgroup setup was skipped or failed silently earlier; Nomad version changes around cgroup v1/v2 handling leaving path unset.
Related errors
- failed to configure container(%s): %v
- configureCgroups: %w
- ErrCgroupMustBeSet
- unable to get orphaned task PIDs: %v
- unable to send signal to process %d: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/408ad8ab34712b9d.
Report an issue: GitHub.