rust-lang/cargo · error · io::Error

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

Error message

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

What it means

Returned as an `io::Error` from `ProcessBuilder::build_command` argfile creation (crates/cargo-util/src/process_builder.rs:471) when an argument's `OsString` cannot be converted to a `str` via `to_str()` — i.e. it contains non-UTF8 bytes. The argfile format requires writing each argument as a line of text, so non-UTF8 args cannot be serialized and the whole argfile build fails.

Source

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

    /// 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 0e07a15537)

Solutions

  1. Ensure all paths and arguments passed to the build are valid UTF-8 (rename offending files).
  2. Reduce argument count/length so cargo does not need an argfile (fewer features, smaller crate, split workspace).
  3. Set relevant env vars (e.g. locale) so tools produce UTF-8 paths.

Example fix

# find and rename non-UTF8 paths cargo is trying to pass
find . -print0 | perl -0 -ne 'print if !/^[\x00-\x7F]*$/'
# rename them to ASCII names, then re-run cargo build
Defensive patterns

Strategy: validation

Validate before calling

fn args_are_utf8(args: &[std::ffi::OsString]) -> bool {
    args.iter().all(|a| a.to_str().is_some())
}
// before relying on argfile fallback, validate args_are_utf8(&args)

Prevention

When it happens

Trigger: Cargo invokes an external command with so many/long arguments that it exceeds the OS arg-length limit and falls back to an `@argfile`; one of those arguments is a path or value containing non-UTF8 bytes (Unix). `arg.to_str()` returns `None` and the error is raised.

Common situations: Building on Linux where a source path or env-derived value contains non-UTF8 bytes; very large dependency graphs pushing rustc invocation over ARG_MAX; paths from unzipped archives with mojibake names; locale mismatches.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/9f21dcbd698feed5.json. Report an issue: GitHub.