{"id":"9364e24e64cff0ba","repo":"rust-lang/rust","slug":"failed-to-mmap-lto-bitcode-file","errorCode":null,"errorMessage":"failed to mmap LTO bitcode file `{}`: {}","messagePattern":"failed to mmap LTO bitcode file `(.+?)`: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_ssa/src/back/lto.rs","lineNumber":61,"sourceCode":"    pub modules: Vec<SerializedModule<B::ModuleBuffer>>,\n    pub module_names: Vec<CString>,\n}\n\npub enum SerializedModule<M: ModuleBufferMethods> {\n    Local(M),\n    FromRlib(Vec<u8>),\n    FromUncompressedFile(Mmap),\n}\n\nimpl<M: ModuleBufferMethods> SerializedModule<M> {\n    pub fn from_file(bc_path: &Path) -> Self {\n        let file = fs::File::open(&bc_path).unwrap_or_else(|e| {\n            panic!(\"failed to open LTO bitcode file `{}`: {}\", bc_path.display(), e)\n        });\n\n        let mmap = unsafe {\n            Mmap::map(file).unwrap_or_else(|e| {\n                panic!(\"failed to mmap LTO bitcode file `{}`: {}\", bc_path.display(), e)\n            })\n        };\n        SerializedModule::FromUncompressedFile(mmap)\n    }\n\n    pub fn data(&self) -> &[u8] {\n        match *self {\n            SerializedModule::Local(ref m) => m.data(),\n            SerializedModule::FromRlib(ref m) => m,\n            SerializedModule::FromUncompressedFile(ref m) => m,\n        }\n    }\n}\n\nfn crate_type_allows_lto(crate_type: CrateType) -> bool {\n    match crate_type {\n        CrateType::Executable\n        | CrateType::Dylib","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_ssa/src/back/lto.rs#L43-L79","documentation":"Raised by SerializedModule::from_file in the LTO pipeline after a bitcode file was successfully opened but could not be memory-mapped. The panic happens inside Mmap::map, meaning the open() succeeded but the OS refused to map the file's bytes into the address space. rustc uses mmap here to avoid copying potentially large bitcode blobs pulled out of rlibs during fat/thin LTO.","triggerScenarios":"Mmap::map(file) returns Err immediately after fs::File::open succeeded, while constructing a SerializedModule for an LTO bitcode file. Concrete causes: file truncated/removed between open and mmap, mmap resource limits (RLIMIT_AS / vm.overcommit), filesystem that does not support mmap (some FUSE/NFS configs, certain network FS), file size of zero, or permission/SELinux denial on the map syscall.","commonSituations":"Building large crates with -C lto=fat or thin on memory-constrained CI runners; cross-compiling with bitcode stored on a network mount; /tmp mounted tmpfs with restrictive overcommit; concurrent builds mutating the same target dir; running out of address space under 32-bit toolchains.","solutions":["Check the underlying errno from the panic message (PermissionDenied, ENOMEM, ENODEV, etc.) and address that specifically","Free address space / raise vm.overcommit or RLIMIT_AS, or move to a 64-bit toolchain","Move the cargo target dir off network/odd filesystems onto a local disk that supports mmap","Ensure no second build is mutating the target directory concurrently (use a unique target dir per job)","Disable LTO for the failing crate (-C lto=off) if the environment cannot mmap"],"exampleFix":"# before\nRUSTFLAGS=\"-C lto=fat\" cargo build --release\n# after (on a no-mmap FS / memory-tight runner)\nRUSTFLAGS=\"-C lto=thin -C codegen-units=16\" cargo build --release","handlingStrategy":"validation","validationCode":"use std::path::Path;\nuse std::fs;\n\nfn ensure_lto_bitcode_readable(path: &Path) -> std::io::Result<()> {\n    if !path.exists() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::NotFound,\n            format!(\"LTO bitcode file not found: {}\", path.display()),\n        ));\n    }\n    let meta = fs::metadata(path)?;\n    if meta.len() == 0 {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            \"LTO bitcode file is empty (possible truncated write)\",\n        ));\n    }\n    let file = fs::File::open(path)?;\n    if file.metadata()?.permissions().readonly() {\n        // mmap of read-only is fine for LTO read; only warn if write-backed mmap expected\n    }\n    Ok(())\n}\n\n// before invoking the LTO/back-end entry point:\n// ensure_lto_bitcode_readable(&path)?;","typeGuard":"// mmap failure surfaces as std::io::Error; narrow on the kind rather than text.\nfn is_mmap_error(e: &std::io::Error) -> bool {\n    matches!(\n        e.kind(),\n        std::io::ErrorKind::UnexpectedEof\n            | std::io::ErrorKind::InvalidData\n            | std::io::ErrorKind::PermissionDenied\n            | std::io::ErrorKind::OutOfMemory\n    ) || e.raw_os_error().map_or(false, |c| {\n        // ENOMEM, EACCES, ENOENT, EFBIG, ENODEV, EOVERFLOW\n        matches!(c, 12 | 13 | 2 | 27 | 19 | 75)\n    })\n}","tryCatchPattern":"match lto::run(&path) {\n    Ok(out) => out,\n    Err(ref e) if is_mmap_error(e) => {\n        // transient (NFS, tmpfs pressure) -> one bounded retry with a fresh fd\n        eprintln!(\"warning: mmap failed for {}: {}; remapping\", path.display(), e);\n        lto::run(&path).expect(\"mmap retry failed\")\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Verify the bitcode file is fully flushed and closed on the producing side before the consuming side mmaps it (partial writes mmap as garbage).","Avoid placing LTO bitcode on filesystems that do not support mmap (some FUSE mounts, network FS with mandatory locking); prefer local tmpfs/disk.","Free address-space pressure before large LTO runs on 32-bit targets; close other mmaps first.","Run with the same UID/GID that owns the bitcode file to avoid EACCES on mmap.","Check free RAM and swap before LTO; mmap-backed reads still fault pages in and can OOM."],"tags":["lto","mmap","codegen","filesystem","linking"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}