rust-lang/rust · error
{context}: {err}
Error message
{context}: {err} What it means
This is the io_error_context helper, not a standalone error. It wraps an underlying io::Error with a descriptive prefix so that low-level filesystem failures during archive writing carry context about which operation failed. Within archive.rs it prefixes two operations: 'failed to rename archive file' (the atomic rename of the temp archive to its final path) and 'failed to remove temporary directory' (cleaning up the temp dir). The {err} part is the original OS error.
Source
Thrown at compiler/rustc_codegen_ssa/src/back/archive.rs:721
let any_entries = !entries.is_empty();
drop(entries);
// Drop src_archives to unmap all input archives, which is necessary if we want to write the
// output archive to the same location as an input archive on Windows.
drop(self.src_archives);
fs::rename(archive_tmpfile_path, output)
.map_err(|err| io_error_context("failed to rename archive file", err))?;
archive_tmpdir
.close()
.map_err(|err| io_error_context("failed to remove temporary directory", err))?;
Ok(any_entries)
}
}
fn io_error_context(context: &str, err: io::Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, format!("{context}: {err}"))
}
View on GitHub (pinned to 22057b88b0)
Solutions
- Ensure TMPDIR / cargo target dir and the final output path are on the same filesystem/mount.
- Check write permissions and free disk space on the output directory.
- On Windows, disable or exclude the target directory from antivirus/on-access scanning and close editors/IDEs holding the file.
- Retry the build after clearing stale locks; if it persists, capture the OS errno from {err} and address it specifically.
Defensive patterns
Strategy: try-catch
Validate before calling
// Generic wrapper around an underlying archive error.
// Pre-flight: try to open and parse the archive so the
// underlying error surfaces before rustc sees it.
fn archive_preflight(path: &std::path::Path) -> Result<(), String> {
std::process::Command::new("ar")
.args(["t", path.to_str().unwrap()])
.output()
.map_err(|e| e.to_string())
.and_then(|o| {
if o.status.success() { Ok(()) }
else { Err(format!("{}", String::from_utf8_lossy(&o.stderr))) }
})
} Type guard
fn is_openable_archive(path: &std::path::Path) -> bool {
archive_preflight(path).is_ok()
} Try / catch
// The message is "{context}: {err}"; parse the context to classify.
let stderr = String::from_utf8_lossy(&output.stderr);
for line in stderr.lines() {
if let Some((ctx, err)) = line.split_once(": ") {
report(ResolveError::Archive { context: ctx.into(), detail: err.into() });
}
} Prevention
- Run the archive preflight above for every native dependency before `cargo build`.
- Surface the `{context}` portion to users so the underlying OS/tool error is not lost.
- Keep `llvm-ar`/`ar` on PATH and at a version compatible with the archive format.
When it happens
Trigger: Produced when fs::rename of the freshly written temp archive to the output path fails, or when tempdir cleanup fails. The prefix tells you which step; the suffix carries the OS-level reason (permission denied, cross-device, busy, etc.).
Common situations: Output path on a different filesystem/mount than the temp dir, making the atomic rename a cross-device move that the OS rejects. Permission/ownership mismatch on the target directory. Antivirus or file-locking software (common on Windows) holding the output file open. The destination being read-only or on a full disk.
Related errors
- Failed to remove {path}: {err}
- Failed to read contents of {path}: {err}
- Failed to remove {path}: {err}
- failed to create {dst:?}: {e}
- failed to copy {src:?}->{dst:?}: {e}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/2e647dcd56b71679.json.
Report an issue: GitHub.