{"id":"4ca165d52bef76e1","repo":"rust-lang/rust","slug":"wanted-an-rlib","errorCode":null,"errorMessage":"wanted an rlib","messagePattern":"wanted an rlib","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_codegen_llvm/src/back/lto.rs","lineNumber":99,"sourceCode":"    // should have default visibility.\n    symbols_below_threshold.push(c\"__llvm_profile_counter_bias\".to_owned());\n\n    // LTO seems to discard this otherwise under certain circumstances.\n    symbols_below_threshold.push(c\"rust_eh_personality\".to_owned());\n\n    // If we're performing LTO for the entire crate graph, then for each of our\n    // upstream dependencies, find the corresponding rlib and load the bitcode\n    // from the archive.\n    //\n    // We save off all the bytecode and LLVM module ids for later processing\n    // with either fat or thin LTO\n    let mut upstream_modules = Vec::new();\n    for path in each_linked_rlib_for_lto {\n        let archive_data = unsafe {\n            Mmap::map(std::fs::File::open(&path).expect(\"couldn't open rlib\"))\n                .expect(\"couldn't map rlib\")\n        };\n        let archive = ArchiveFile::parse(&*archive_data).expect(\"wanted an rlib\");\n        let metadata_link = rmeta_link::read(&archive, &archive_data, &path).unwrap();\n        let obj_files = archive\n            .members()\n            .filter_map(|child| {\n                child\n                    .ok()\n                    .and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)))\n            })\n            .filter(|&(name, _)| metadata_link.rust_object_files.iter().any(|f| f == name));\n        for (name, child) in obj_files {\n            info!(\"adding bitcode from {}\", name);\n            match get_bitcode_slice_from_object_data(\n                child.data(&*archive_data).expect(\"corrupt rlib\"),\n                cgcx,\n            ) {\n                Ok(data) => {\n                    let module = SerializedModule::FromRlib(data.to_vec());\n                    upstream_modules.push((module, CString::new(name).unwrap()));","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_llvm/src/back/lto.rs#L81-L117","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before: rlib path holds a non-archive file\ncargo build --release  # panic: wanted an rlib\n$ file target/release/deps/libfoo-*.rlib\n# target/release/deps/libfoo-*.rlib: data   (NOT 'current ar archive')\n\n# after: regenerate valid rlibs\ncargo clean\ncargo build --release","handlingStrategy":"fallback","validationCode":"fn is_ar_archive(path: &std::path::Path) -> std::io::Result<bool> {\n    use std::io::Read;\n    let mut f = std::fs::File::open(path)?;\n    let mut magic = [0u8; 8];\n    f.read_exact(&mut magic)?;\n    Ok(&magic == b\"!<arch>\\n\")\n}","typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(|| invoke_lto()) {\n    Ok(v) => v,\n    Err(_) => { eprintln!(\"rlib not a valid archive; rebuilding dependency\"); rebuild_and_retry(); }\n}","preventionTips":["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."],"tags":["rustc","lto","codegen","archive","corruption"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}