{"record":{"id":"c40bb282ed7cbabd","repo":"rust-lang/rust","slug":"failed-to-open-nul-device-for-child-stream-e","errorCode":null,"errorMessage":"failed to open NUL device for child {stream}: {e}","messagePattern":"failed to open NUL device for child (.+?): (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"library/std/src/sys/process/windows.rs","lineNumber":655,"sourceCode":"            // processes (as this is about to be inherited).\n            Stdio::Null => {\n                let mut opts = OpenOptions::new();\n                opts.read(stdio_id == c::STD_INPUT_HANDLE);\n                opts.write(stdio_id != c::STD_INPUT_HANDLE);\n                opts.inherit_handle(true);\n                File::open(Path::new(r\"\\\\.\\NUL\"), &opts).map(|file| file.into_inner()).map_err(\n                    |e| {\n                        // A raw `NotFound` here is easily mistaken for the program\n                        // being missing, so say what actually failed to open.\n                        // `spawn` only passes the three standard ids, but print\n                        // anything else as a number rather than mislabeling it.\n                        let stream = match stdio_id {\n                            c::STD_INPUT_HANDLE => \"stdin\".to_string(),\n                            c::STD_OUTPUT_HANDLE => \"stdout\".to_string(),\n                            c::STD_ERROR_HANDLE => \"stderr\".to_string(),\n                            id => format!(\"stdio handle {id}\"),\n                        };\n                        Error::new(\n                            e.kind(),\n                            format!(\"failed to open NUL device for child {stream}: {e}\"),\n                        )\n                    },\n                )\n            }\n        }\n    }\n}\n\nimpl From<ChildPipe> for Stdio {\n    fn from(pipe: ChildPipe) -> Stdio {\n        Stdio::Pipe(pipe)\n    }\n}\n\nimpl From<Handle> for Stdio {\n    fn from(pipe: Handle) -> Stdio {","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/library/std/src/sys/process/windows.rs#L637-L673","documentation":"Produced by Rust std's Windows process spawner when Stdio::Null is configured for a child stream and opening the NUL device (\\\\.\\NUL) fails. std deliberately re-wraps the raw NotFound error to name which stream (stdin/stdout/stderr) could not be bound, because a bare NotFound here is easily misread as the spawned program being missing. The underlying error kind and message are preserved inside the new message.","triggerScenarios":"Command::spawn on Windows with stdin/stdout/stdout set to Stdio::null() (the default for unconfigured streams on some paths) when File::open(\"\\\\.\\NUL\", ...) fails - e.g. NUL device disabled/renamed, extreme handle exhaustion, antivirus intercepting device opens, or a locked-down environment blocking device namespace access.","commonSituations":"Sandboxed/CI runner that restricts the \\\\.\\NUL device; broken Windows image or security product hooking CreateFileW on device paths; running under a context where the NUL device symlink is missing.","solutions":["Provide explicit Stdio::piped() or an inherited handle instead of Stdio::null() for the failing stream.","Check the embedded inner error ({e}) - if it indicates handle exhaustion, reduce open handles or raise the process quota.","Run on a normal Windows installation or relax the sandbox that blocks the \\\\.\\NUL device path.","Disable/reconfigure antivirus hooks that intercept device-path file opens."],"exampleFix":"// before\nlet child = Command::new(\"tool\")\n    .stdout(Stdio::null())\n    .stderr(Stdio::null())\n    .spawn()?;\n\n// after (pipe instead of NUL)\nlet child = Command::new(\"tool\")\n    .stdout(Stdio::piped())\n    .stderr(Stdio::piped())\n    .spawn()?;","handlingStrategy":"fallback","validationCode":"fn pick_stdio() -> std::process::Stdio {\n    // If NUL is known-restricted, pipe instead of null.\n    if std::fs::File::open(r\"\\\\.\\NUL\").is_err() {\n        std::process::Stdio::piped()\n    } else {\n        std::process::Stdio::null()\n    }\n}","typeGuard":null,"tryCatchPattern":"match Command::new(t).stdout(Stdio::null()).spawn() {\n    Ok(c) => Ok(c),\n    Err(e) if e.to_string().contains(\"failed to open NUL device\") => {\n        Command::new(t).stdout(Stdio::piped()).spawn()\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Prefer explicit Stdio::piped() or inherited handles when NUL may be restricted.","Check handle counts if the inner error suggests exhaustion.","Avoid sandbox/AV configurations that block the \\\\.\\NUL device path."],"tags":["rust","std","process","windows","stdio","spawn","io"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}