windmill-labs/windmill · error
SetInformationJobObject: {e}
Error message
SetInformationJobObject: {e} What it means
After creating a Windows Job object, assign_job_object configures its limits (memory limits, and JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE when requested) via SetInformationJobObject. If that call fails, the job handle is closed and an io::Error with this message is returned.
Source
Thrown at backend/windmill-worker/src/common.rs:894
let mut info = JOBOBJECT_EXTENDED_LIMIT_INFORMATION::default();
if kill_on_close {
info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
}
if let Some(memory_limit) = memory_limit {
info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_JOB_MEMORY;
info.JobMemoryLimit = memory_limit;
}
SetInformationJobObject(
job,
JobObjectExtendedLimitInformation,
&info as *const _ as _,
std::mem::size_of::<JOBOBJECT_EXTENDED_LIMIT_INFORMATION>() as u32,
)
.map_err(|e| {
let _ = windows::Win32::Foundation::CloseHandle(job);
std::io::Error::new(
std::io::ErrorKind::Other,
format!("SetInformationJobObject: {e}"),
)
})?;
let process_handle = OpenProcess(PROCESS_SET_QUOTA | PROCESS_TERMINATE, false, pid)
.map_err(|e| {
let _ = windows::Win32::Foundation::CloseHandle(job);
std::io::Error::new(
std::io::ErrorKind::Other,
format!("OpenProcess({pid}): {e}"),
)
})?;
let assign_result = AssignProcessToJobObject(job, process_handle);
let _ = windows::Win32::Foundation::CloseHandle(process_handle);
assign_result.map_err(|e| {
let _ = windows::Win32::Foundation::CloseHandle(job);View on GitHub (pinned to e474e8803c)
Solutions
- Read the Win32 error code in the message; ERROR_ACCESS_DENIED usually means a sandbox disallows the requested limits.
- Drop the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE / memory-limit flags if the environment forbids them, or run the worker outside the restricted container.
- Update the `windows` crate; struct layout mismatches can cause the call to be rejected.
- Retry the job; if consistent, it is environmental rather than transient.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check not exposed; confirm the deployment OS supports JOBOBJECT_EXTENDED_LIMIT_INFORMATION (Windows with full job object support) and the worker is not inside a restricting sandbox.
Try / catch
match assign_job_object(pid, true) {
Err(e) if e.to_string().contains("SetInformationJobObject") => {
log::error!("job limits rejected by OS/environment: {e}; falling back to plain child");
// degrade: spawn without job object, track pid for manual kill
}
other => other?,
} Prevention
- Deploy workers outside nested-job containers when possible
- Keep the `windows` crate version current to avoid struct-layout mismatches
- Avoid security policies that strip job object limit rights
When it happens
Trigger: assign_job_object on Windows with JOBOBJECT_EXTENDED_LIMIT_INFORMATION that the OS rejects — e.g. requesting limit flags unsupported by the Windows edition (memory limits in certain containers/sessions) or invalid limit structure.
Common situations: Running inside nested job objects/containers where extended limit information is restricted; old or stripped Windows editions; misaligned struct size when the windows crate version mismatches the OS expectations.
Related errors
- CreateToolhelp32Snapshot: {e}
- CreateJobObjectW: {e}
- AssignProcessToJobObject: {e}
- OpenProcess({pid}): {e}
- preprocessor function is missing
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/8888dced52030d04.
Report an issue: GitHub.