microsoft/aspire · error · Win32Exception
Failed to add job object to process thread attribute list
Error message
Failed to add job object to process thread attribute list
What it means
The Aspire CLI attaches the kill-on-parent-exit Job Object to a spawned child via UpdateProcThreadAttribute with ProcThreadAttributeJobList so the child is assigned to the job at creation time. This error is thrown when that specific attribute update fails, wrapped with the last Win32 error. The child would then not be bound to the job, so CLI crash-cleanup cannot guarantee its termination.
Solutions
- Read the inner Win32Exception code; ERROR_ACCESS_DENIED on the job handle points to outer-job nesting restrictions.
- Run the CLI outside restrictive job environments (adjust CI runner configuration or use breakaway).
- Retry the operation to rule out a transient SafeHandle lifetime race.
- Update/report the issue to the Aspire CLI if reproducible outside sandboxed environments.
Defensive patterns
Strategy: try-catch
Try / catch
try
{
await runner.StartAsync(exe, args, killOnParentExit: true);
}
catch (Win32Exception ex)
{
logger.LogWarning("Job-list attribute failed (Win32 error {Code}); child may outlive the CLI.", ex.ErrorCode);
} Prevention
- Do not nest the CLI inside foreign Job Objects with restrictive limits (CI runners).
- Prefer running the CLI directly in a session rather than under job-wrapping supervisors.
- Check EDR policies that block job-list process attributes.
When it happens
Trigger: Starting a Windows child process with killOnParentExit enabled where UpdateProcThreadAttribute(ProcThreadAttributeJobList) returns false — commonly when the job handle is invalid, the job has JOB_OBJECT_LIMIT_BREAKAWAY_OK restrictions conflicting with the target, or the process is already inside an incompatible job.
Common situations: Running the CLI inside an outer job (CI runners, container runtimes, RDP session jobs) that does not permit nested job assignment; job handle SafeHandle was released before the call (DangerousAddRef race); EDR blocking job-list attributes.
Related errors
- Failed to configure CLI kill-on-parent-exit job object…
- Failed to create process
- Failed to initialize process thread attribute list
- Failed to create CLI kill-on-parent-exit job object
- Failed to update process thread attribute list
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/341d9be9a43bd669.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Processes/WindowsProcessInterop.cs:431
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "Failed to update process thread attribute list");
}
if (jobHandle is not null)
{
jobHandle.DangerousAddRef(ref jobHandleRefAdded);
var jobHandles = new[] { jobHandle.DangerousGetHandle() };
pinnedJobHandles = GCHandle.Alloc(jobHandles, GCHandleType.Pinned);
if (!UpdateProcThreadAttribute(
attrList,
0,
ProcThreadAttributeJobList,
pinnedJobHandles.AddrOfPinnedObject(),
(nint)(nint.Size * jobHandles.Length),
nint.Zero,
nint.Zero))
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "Failed to add job object to process thread attribute list");
}
}
var si = new STARTUPINFOEX
{
cb = Marshal.SizeOf<STARTUPINFOEX>(),
dwFlags = StartfUseStdHandles | StartfUseShowWindow,
hStdInput = stdio.Stdin,
hStdOutput = stdio.Stdout,
hStdError = stdio.Stderr,
lpAttributeList = attrList,
// CREATE_NO_WINDOW is ignored with CREATE_NEW_CONSOLE; SW_HIDE keeps
// the new console window off-screen.
wShowWindow = ShowWindowHide,
};
var commandLine = BuildCommandLine(fileName, arguments);
View on GitHub (pinned to 25830f84bd)