microsoft/aspire · error · Win32Exception
Failed to set NUL stdin handle inheritance
Error message
Failed to set NUL stdin handle inheritance
What it means
After opening NUL for the child's stdin, the CLI must mark that handle inheritable (SetHandleInformation with HANDLE_FLAG_INHERIT) so the spawned child can actually use it. When SetHandleInformation returns FALSE, a Win32Exception with the underlying Win32 error code is thrown. This happens before the child is created, so no orphan process is left behind.
Solutions
- Read NativeErrorCode: ERROR_INVALID_HANDLE points at handle creation failing earlier — fix the upstream 'Failed to open NUL device for stdin' condition first.
- Check whether security software or a restricted token/job is interfering with handle manipulation and run with a normal user token.
- Reproduce with a minimal `cmd /c dir > NUL` style test to confirm handle inheritance works in the environment.
- Update or reinstall the Aspire CLI; report persistent occurrences with the Win32 error code.
Defensive patterns
Strategy: try-catch
Try / catch
try
{
var process = isolatedProcess.Start(startInfo);
}
catch (Win32Exception ex) when (ex.Message == "Failed to set NUL stdin handle inheritance")
{
// Check ex.NativeErrorCode: 6 => upstream open failed; 5 => security policy
} Prevention
- Resolve any 'Failed to open NUL device for stdin' errors first — this error is usually downstream of a bad handle.
- Run the CLI under a normal (non-restricted) user token.
- Audit EDR/AV policies that hook SetHandleInformation.
- Keep the Aspire CLI updated so handle-lifecycle bugs are patched.
When it happens
Trigger: StartWindows calls WindowsProcessInterop.SetHandleInformation(nulStdinHandle, HandleFlagInherit, HandleFlagInherit) and it returns false — Marshal.GetLastWin32Error() typically yields ERROR_INVALID_HANDLE (6) or ERROR_ACCESS_DENIED (5).
Common situations: The NUL handle was already disposed/closed due to a race or earlier failure, security software stripping handle flags, or a corrupted handle value from a failed CreateFileW path that slipped past the IsInvalid check.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Failed to set NUL handle inheritance
- Failed to create CLI kill-on-parent-exit job object
- Failed to invoke UpdateProcThreadAttribute while starting…
- Failed to open NUL device
- Failed to open NUL device for stdin
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e5272d824cff0627.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Processes/IsolatedProcess.Windows.cs:61
WindowsProcessInterop.FileShareRead,
nint.Zero,
WindowsProcessInterop.OpenExisting,
0,
nint.Zero);
if (nulStdinHandle.IsInvalid)
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open NUL device for stdin");
}
AnonymousPipeServerStream? stdoutPipe = null;
AnonymousPipeServerStream? stderrPipe = null;
try
{
if (!WindowsProcessInterop.SetHandleInformation(nulStdinHandle, WindowsProcessInterop.HandleFlagInherit, WindowsProcessInterop.HandleFlagInherit))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to set NUL stdin handle inheritance");
}
// PipeDirection.In = server reads, client writes. Inheritable is REQUIRED:
// PROC_THREAD_ATTRIBUTE_HANDLE_LIST restricts WHICH handles get inherited but does
// NOT promote non-inheritable handles to inheritable ones. Without this flag the
// child would see ERROR_INVALID_HANDLE on its stdout/stderr writes.
stdoutPipe = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
stderrPipe = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
var stdio = new WindowsProcessInterop.StdioHandles(
Stdin: nulStdinHandle.DangerousGetHandle(),
Stdout: stdoutPipe.ClientSafePipeHandle.DangerousGetHandle(),
Stderr: stderrPipe.ClientSafePipeHandle.DangerousGetHandle());
// Pass the caller's environment (if touched) verbatim to the spawn primitive;
// null = inherit parent env block.
var environment = startInfo.GetEnvironmentForSpawn();
View on GitHub (pinned to 25830f84bd)