hashicorp/nomad · error

could not create Windows job object for executor: %w

Error message

could not create Windows job object for executor: %w

What it means

Nomad's Windows executor creates a Job Object (with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) so all child processes die when the executor exits. If windows.CreateJobObject fails (kernel call error, out of handles, security policy), the executor wraps and returns the error instead of running the task without cleanup guarantees.

Source

Thrown at drivers/shared/executor/executor_windows.go:128

func (e *UniversalExecutor) setSubCmdCgroup(*exec.Cmd, string) (func(), error) {
	return func() {}, nil
}

// configure new process group for child process and creates a JobObject for the
// executor. Children of the executor will be created in the same JobObject
// Ref: https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects
func (e *UniversalExecutor) setNewProcessGroup() error {
	// We need to check that as build flags includes windows for this file
	if e.childCmd.SysProcAttr == nil {
		e.childCmd.SysProcAttr = &syscall.SysProcAttr{}
	}
	e.childCmd.SysProcAttr.CreationFlags = syscall.CREATE_NEW_PROCESS_GROUP

	// note: we don't call CloseHandle on this job handle because we need to
	// hold onto it until the executor exits
	job, err := windows.CreateJobObject(nil, nil)
	if err != nil {
		return fmt.Errorf("could not create Windows job object for executor: %w", err)
	}

	info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{
		BasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{
			LimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
		},
	}
	_, err = windows.SetInformationJobObject(
		job,
		windows.JobObjectExtendedLimitInformation,
		uintptr(unsafe.Pointer(&info)),
		uint32(unsafe.Sizeof(info)))
	if err != nil {
		return fmt.Errorf("could not configure Windows job object for executor: %w", err)
	}

	handle := windows.CurrentProcess()
	err = windows.AssignProcessToJobObject(job, handle)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Re-run as a privileged/service account and retry; inspect the wrapped Windows error code via '%v'.
  2. Check antivirus/EDR software for job-object creation hooks and add exclusions for the Nomad/executor binaries.
  3. Free system resources (handles, commit memory) on the host and restart the Nomad client.
  4. Reboot the host if kernel object tables are exhausted (event log will show resource errors).

Example fix

// before
C:\> nomad.exe agent -dev  # under restrictive AV, job object creation fails
// after: add exclusion
Set-MpPreference -ExclusionProcess "nomad.exe","nomad_executor.exe"  # or adjust EDR policy, then restart the client
Defensive patterns

Strategy: fallback

Validate before calling

// Go: probe job-object creation capability before scheduling tasks
if _, err := windows.CreateJobObject(nil, nil); err != nil {
    return fmt.Errorf("host cannot create job objects: %w", err)
}

Try / catch

if err := e.setNewProcessGroup(); err != nil {
    if strings.Contains(err.Error(), "create Windows job object") {
        // degraded mode: still launch but child procs may outlive executor;
        // alert and mark client unhealthy instead
    }
    return err
}

Prevention

When it happens

Trigger: windows.CreateJobObject(nil, nil) returns a non-nil error — kernel object creation failure, exhausted handles, or restrictive security software blocking job object creation.

Common situations: Hosts with endpoint/AV software hooking kernel object creation; severe handle/memory exhaustion; hardened Windows images with restricted object creation for the service account.

Related errors


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