rust-lang/cargo · error

argument for argfile contains invalid UTF-8 characters

Error message

argument for argfile contains invalid UTF-8 characters: `{}`

What it means

In `ProcessBuilder::get_command_and_argfile` (cargo-util), Cargo serializes its arguments into a temporary argfile (one per line) when the argument list is large. Each `OsString` argument is converted to `&str` via `to_str()`; if any argument contains non-UTF-8 bytes the conversion fails and an `io::Error` (kind `Other`) is returned with the lossy rendering of the argument. The argfile format is line-delimited UTF-8 text, so non-UTF-8 arguments cannot be represented.

Solutions

  1. Ensure every argument passed to the `ProcessBuilder` is valid UTF-8 before triggering argfile creation.
  2. Sanitize or percent-encode any path argument that may carry non-UTF-8 bytes.
  3. Avoid deriving `ProcessBuilder` arguments from raw OS strings of unknown encoding.

Example fix

// before
let arg: OsString = ...; // may contain non-UTF-8 bytes
pb.arg(arg);

// after: validate / sanitize first
let arg = arg.into_string().map_err(|_| "non-utf8 arg")?;
pb.arg(arg);
Defensive patterns

Strategy: validation

Validate before calling

use std::ffi::OsString;
fn args_all_utf8(args: &[OsString]) -> Result<(), String> {
    for a in args {
        a.to_str().ok_or_else(|| format!("non-utf8 arg: {:?}", a))?;
    }
    Ok(())
}
// call before constructing a ProcessBuilder that may trigger argfile mode

Prevention

When it happens

Trigger: Building a `ProcessBuilder` whose `args` contain an `OsString` with non-UTF-8 bytes, then calling the method that materializes the argfile (used when command-line length limits force an argfile). Common with non-UTF-8 environment-derived paths or user-supplied arguments on Unix.

Common situations: Passing a file path argument that contains non-UTF-8 bytes (rare, but possible on Unix), or a crate/tool name generated from a non-UTF-8 source. Surfaces only when the argument count/size triggers argfile mode.

Understand the failure class

Related errors


AI-assisted analysis of rust-lang/cargo@42eee92bc9 (2026-08-11). Data as JSON: /api/errors/9f21dcbd698feed5. Report an issue: GitHub.

Appendix: source

Thrown at crates/cargo-util/src/process_builder.rs:504

    /// arguments. This is primarily served for rustc/rustdoc command family.
    fn build_command_with_argfile(&self) -> io::Result<(Command, NamedTempFile)> {
        use std::io::Write as _;

        let mut tmp = tempfile::Builder::new()
            .prefix("cargo-argfile.")
            .tempfile()?;

        let mut arg = OsString::from("@");
        arg.push(tmp.path());
        let mut cmd = self.build_command_without_args();
        cmd.arg(arg);
        tracing::debug!("created argfile at {} for {self}", tmp.path().display());

        let cap = self.get_args().map(|arg| arg.len() + 1).sum::<usize>();
        let mut buf = Vec::with_capacity(cap);
        for arg in &self.args {
            let arg = arg.to_str().ok_or_else(|| {
                io::Error::new(
                    io::ErrorKind::Other,
                    format!(
                        "argument for argfile contains invalid UTF-8 characters: `{}`",
                        arg.to_string_lossy()
                    ),
                )
            })?;
            if arg.contains('\n') {
                return Err(io::Error::new(
                    io::ErrorKind::Other,
                    format!("argument for argfile contains newlines: `{arg}`"),
                ));
            }
            writeln!(buf, "{arg}")?;
        }
        tmp.write_all(&mut buf)?;
        Ok((cmd, tmp))
    }

View on GitHub (pinned to 42eee92bc9)