denoland/deno · error · ProcessError::Io

nul byte found in provided data

Error message

nul byte found in provided data

What it means

When spawning a subprocess, the cwd path must be converted to a CString for the OS exec. Rust's CString::new rejects any byte sequence containing interior NUL bytes; the resulting error is surfaced as an InvalidInput io error ('nul byte found in provided data') from create_command (reached via op_spawn_child, op_node_spawn_child, op_spawn_sync).

Source

Thrown at ext/process/lib.rs:782

    }
    command.args(args.args);
  }

  #[cfg(unix)]
  let uid = args.uid;
  #[cfg(unix)]
  let gid = args.gid;
  #[cfg(unix)]
  let move_cwd_to_pre_exec =
    should_change_cwd_in_pre_exec(uid, gid, run_env.set_cwd_on_command);
  // Rust applies built-in uid/gid changes before current_dir, but applies
  // current_dir before user pre_exec callbacks. Defer it into our callback so
  // replacing the built-in identity setup preserves uid/gid-before-cwd order.
  #[cfg(unix)]
  let pre_exec_cwd = if move_cwd_to_pre_exec {
    Some(
      CString::new(run_env.cwd.as_os_str().as_bytes()).map_err(|err| {
        ProcessError::Io(std::io::Error::new(
          std::io::ErrorKind::InvalidInput,
          err,
        ))
      })?,
    )
  } else {
    None
  };

  #[cfg(unix)]
  if run_env.set_cwd_on_command && !move_cwd_to_pre_exec {
    command.current_dir(&run_env.cwd);
  }
  #[cfg(windows)]
  if run_env.set_cwd_on_command {
    command.current_dir(&run_env.cwd);
  }
  command.env_clear();

View on GitHub (pinned to a961cdec3b)

Solutions

  1. Strip NUL bytes from cwd before spawning: cwd.replaceAll('\0', '') or truncate at the first NUL.
  2. Validate the cwd string (no '\u0000') before constructing Deno.Command.
  3. If the path came from a byte buffer, decode with the NUL terminator removed instead of including it.

Example fix

// before
new Deno.Command('ls', { cwd: cwdFromBuffer }); // may contain \0
// after
const cwd = cwdFromBuffer.split('\u0000')[0];
new Deno.Command('ls', { cwd });
Defensive patterns

Strategy: validation

Validate before calling

function sanitizePath(p) {
  if (typeof p !== 'string' || p.includes('\u0000')) {
    throw new TypeError('Path must not contain NUL bytes');
  }
  return p;
}
new Deno.Command(cmd, { cwd: sanitizePath(cwd) });

Type guard

function isNulFreePath(p) {
  return typeof p === 'string' && !p.includes('\u0000');
}

Try / catch

try {
  const child = new Deno.Command(cmd, { cwd }).spawn();
} catch (err) {
  if (String(err.message).includes('nul byte found in provided data')) {
    // retry with cwd = cwd.split('\u0000')[0]
  }
}

Prevention

When it happens

Trigger: Calling Deno.Command (or Node child_process spawn) with a cwd (or related env path handled by the same path) containing a \0 character — typically via a programmatically built string or a path read from a source that preserved NUL bytes.

Common situations: Paths assembled from binary data or fixed-width buffers with padding NULs; env vars or config values read as byte arrays; deserialized paths that include a terminator NUL.

Related errors


AI-assisted analysis of denoland/deno@a961cdec3b (2026-09-03). Data as JSON: /api/errors/08113aaa4ee9cc1c. Report an issue: GitHub.