rust-lang/rust · critical
wanted an rlib
Error message
wanted an rlib
What it means
Thrown by `ArchiveFile::parse(&*archive_data).expect("wanted an rlib")` in lto.rs:99 during LTO. The memory-mapped file was read successfully but the `object` crate could not parse it as an `ar` archive — rlibs are Unix `ar` archives, so this means the file at the recorded dependency path is not actually an rlib (wrong format, corrupted header, or a different file type masquerading under the rlib path).
Source
Thrown at compiler/rustc_codegen_llvm/src/back/lto.rs:99
// should have default visibility.
symbols_below_threshold.push(c"__llvm_profile_counter_bias".to_owned());
// LTO seems to discard this otherwise under certain circumstances.
symbols_below_threshold.push(c"rust_eh_personality".to_owned());
// If we're performing LTO for the entire crate graph, then for each of our
// upstream dependencies, find the corresponding rlib and load the bitcode
// from the archive.
//
// We save off all the bytecode and LLVM module ids for later processing
// with either fat or thin LTO
let mut upstream_modules = Vec::new();
for path in each_linked_rlib_for_lto {
let archive_data = unsafe {
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
.expect("couldn't map rlib")
};
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let metadata_link = rmeta_link::read(&archive, &archive_data, &path).unwrap();
let obj_files = archive
.members()
.filter_map(|child| {
child
.ok()
.and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)))
})
.filter(|&(name, _)| metadata_link.rust_object_files.iter().any(|f| f == name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
match get_bitcode_slice_from_object_data(
child.data(&*archive_data).expect("corrupt rlib"),
cgcx,
) {
Ok(data) => {
let module = SerializedModule::FromRlib(data.to_vec());
upstream_modules.push((module, CString::new(name).unwrap()));View on GitHub (pinned to 22057b88b0)
Solutions
- Run `cargo clean` and rebuild so the rlib is regenerated by the current toolchain.
- Inspect the file header: `file <path>` and `head -c 8 <path>` should show `!<arch>` for a valid rlib.
- Ensure `target/` is not shared/copied between different OSes or rustc versions; use a fresh target dir per host.
- Check for and remove any manual overwrites or symlinks over rlib paths in `target/`.
- Reinstall/verify the toolchain if the sysroot rlib itself is malformed (`rustup` reinstall).
Example fix
# before: rlib path holds a non-archive file cargo build --release # panic: wanted an rlib $ file target/release/deps/libfoo-*.rlib # target/release/deps/libfoo-*.rlib: data (NOT 'current ar archive') # after: regenerate valid rlibs cargo clean cargo build --release
Defensive patterns
Strategy: fallback
Validate before calling
fn is_ar_archive(path: &std::path::Path) -> std::io::Result<bool> {
use std::io::Read;
let mut f = std::fs::File::open(path)?;
let mut magic = [0u8; 8];
f.read_exact(&mut magic)?;
Ok(&magic == b"!<arch>\n")
} Try / catch
match std::panic::catch_unwind(|| invoke_lto()) {
Ok(v) => v,
Err(_) => { eprintln!("rlib not a valid archive; rebuilding dependency"); rebuild_and_retry(); }
} Prevention
- Never manually edit or truncate files inside target/.
- Do not share a target directory across different rustc/LLVM versions or host triples.
- Use `cargo clean` after switching toolchains (rustup, beta->nightly).
- Avoid third-party tools that rewrite .rlib archives in place.
When it happens
Trigger: Triggered during LTO when `ArchiveFile::parse` returns `Err`: the file at the upstream rlib path has a bad magic header (`!<arch>` missing), is a different artifact type (e.g. a `.so`, `.rmeta`, or text file copied over the rlib path), or the archive header is corrupted by disk/truncation.
Common situations: A previous toolchain-version mismatch where `.rmeta`/metadata was rewritten but the `.rlib` is from an incompatible build; manually overwriting an rlib path with another file; disk corruption or partial writes leaving an invalid archive header; mixing `target` dirs across machines/OSes (e.g. copied `target/` from Windows to Linux); symlink loops pointing an rlib path at a non-archive.
Related errors
- corrupt rlib
- couldn't open rlib
- couldn't map rlib
- unsupported integer: {self:?}
- unsupported float: {self:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/4ca165d52bef76e1.json.
Report an issue: GitHub.