hashicorp/nomad · error

could not configure Windows job object for executor: %w

Error message

could not configure Windows job object for executor: %w

What it means

After creating the job object, the executor configures it with JOBOBJECT_EXTENDED_LIMIT_INFORMATION (KILL_ON_JOB_CLOSE) via SetInformationJobObject. Failure means the limits could not be applied, so the executor refuses to proceed to avoid launching tasks without kill-on-close protection.

Source

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

	// 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)
	if err != nil {
		return fmt.Errorf("could not assign executor to Windows job object: %w", err)
	}

	return nil
}

// Cleanup any still hanging user processes
func (e *UniversalExecutor) killProcessTree(proc *os.Process) error {
	// We must first verify if the process is still running.
	// (Windows process often lingered around after being reported as killed).
	handle, err := syscall.OpenProcess(syscall.PROCESS_TERMINATE|syscall.SYNCHRONIZE|syscall.PROCESS_QUERY_INFORMATION, false, uint32(proc.Pid))
	if err != nil {
		return os.NewSyscallError("OpenProcess", err)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped Windows error code and check the host's System/Application event log for the failing process.
  2. Add AV/EDR exclusions for the Nomad client and executor binaries and retry.
  3. Update Nomad to the latest patch — older versions had struct/size issues on newer Windows builds.
  4. Run the Nomad client under LocalSystem (or an account with the required privileges) and restart.
  5. Apply pending Windows updates and reboot the host.

Example fix

// before
nomad agent -config=... run as low-privilege user 'svc-nomad' with EDR blocking job config
// after
# run client as LocalSystem and exclude binaries from EDR
sc config Nomad obj= LocalSystem
Set-MpPreference -ExclusionProcess "nomad.exe","nomad_executor.exe"
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify job object configuration works before use
job, err := windows.CreateJobObject(nil, nil)
if err != nil {
    return err
}
info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{
    BasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{
        LimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
    },
}
if _, err := windows.SetInformationJobObject(job,
    windows.JobObjectExtendedLimitInformation,
    uintptr(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))); err != nil {
    return fmt.Errorf("job object config unsupported on this host: %w", err)
}

Try / catch

if err := e.setNewProcessGroup(); err != nil {
    if strings.Contains(err.Error(), "configure Windows job object") {
        // log wrapped Windows code; check struct size/OS build and EDR hooks
        return fmt.Errorf("task launch aborted: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: windows.SetInformationJobObject returns an error: invalid handle (job already closed), insufficient privilege, buffer/size mismatch from a Windows API change, or security software interfering.

Common situations: Hardened hosts or EDR blocking JobObject configuration; running on unusual Windows builds where the extended limit info struct differs; driver-level security products tampering with the handle.

Related errors


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