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

  1. Run `cargo clean` and rebuild so the rlib is regenerated by the current toolchain.
  2. Inspect the file header: `file <path>` and `head -c 8 <path>` should show `!<arch>` for a valid rlib.
  3. Ensure `target/` is not shared/copied between different OSes or rustc versions; use a fresh target dir per host.
  4. Check for and remove any manual overwrites or symlinks over rlib paths in `target/`.
  5. 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

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


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/4ca165d52bef76e1.json. Report an issue: GitHub.