denoland/deno · error

nul byte found in provided data

Error message

nul byte found in provided data

What it means

The Windows command line - the executable path and every argument - is encoded as NUL-terminated UTF-16, so process.rs applies the same guard as the environment path: ensure_no_nuls() rejects any program path or argument containing U+0000 with InvalidInput, because an embedded NUL would truncate the command line handed to CreateProcessW.

Source

Thrown at runtime/subprocess_windows/src/process.rs:1601

        ]);
      }
      backslashes = 0;
    }
    cmd.push(x);
  }
  if quote {
    // Add n backslashes to total 2n before ending `"`.
    cmd.extend((0..backslashes).map(|_| '\\' as u16));
    cmd.push('"' as u16);
  }
  Ok(())
}

// lifted from https://github.com/rust-lang/rust/blob/bc1d7273dfbc6f8a11c0086fa35f6748a13e8d3c/library/std/src/sys/pal/windows/mod.rs#L289
// Copyright The Rust Project Contributors - MIT
fn ensure_no_nuls<T: AsRef<OsStr>>(s: T) -> crate::io::Result<T> {
  if s.as_ref().encode_wide().any(|b| b == 0) {
    Err(std::io::Error::new(
      io::ErrorKind::InvalidInput,
      "nul byte found in provided data",
    ))
  } else {
    Ok(s)
  }
}

fn command_prompt() -> io::Result<WCString> {
  let mut buffer =
    vec![0u16; windows_sys::Win32::Foundation::MAX_PATH as usize];
  let len =
    unsafe { GetSystemDirectoryW(buffer.as_mut_ptr(), buffer.len() as u32) };
  if len == 0 {
    return Err(io::Error::last_os_error());
  }
  buffer.truncate(len as usize);
  buffer.extend("\\cmd.exe".encode_utf16().chain([0]));

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Strip U+0000 from the program path and all arguments before spawn
  2. Pass binary payloads via stdin or a temp file rather than argv
  3. Validate at the trust boundary: reject NUL-containing input as soon as it enters your app

Example fix

// before
const c = new Deno.Command("tool", { args: [chunk.toString()] }); // chunk has NULs

// after
const arg = chunk.toString().replaceAll("\u0000", "");
const c = new Deno.Command("tool", { args: [arg] });
Defensive patterns

Strategy: validation

Validate before calling

const hasNul = (s: string) => s.includes("\u0000");
const safeArgs = args.map(String).map((a) => {
  if (hasNul(a)) throw new Error("argument contains NUL byte");
  return a;
});

Type guard

const isNulFree = (s: string): s is string => !s.includes("\u0000");

Try / catch

try {
  const child = new Deno.Command(prog, { args }).spawn();
} catch (err) {
  if (err instanceof TypeError && err.message.includes("nul byte")) {
    // strip U+0000 from prog/args and retry
  } else throw err;
}

Prevention

When it happens

Trigger: new Deno.Command(prog, { args: [...] }).spawn() on Windows where prog or any argument contains a NUL character, e.g. args: ["a\u0000b"], or a file path built from a buffer with embedded NUL terminators.

Common situations: Strings decoded from binary formats or length-prefixed buffers; filenames taken from device listings or network protocols that embed NULs; JSON payloads containing \u0000 escapes passed through to spawn.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/c1976b0cbfc2b71a. Report an issue: GitHub.