rust-lang/rust · error

archive member at offset {start} with size {} exceeds archiv

Error message

archive member at offset {start} with size {} exceeds archive size {} in `{}`

What it means

Returned while copying an entry out of a source archive during output archive assembly: the entry's recorded (offset, size) file_range extends past the end of the memory-mapped source archive bytes. The slice .get(start..end) returns None, so rustc builds an InvalidData io::Error (wrapped by io_error_context) describing the exact offset, member size, total archive size, and archive path. It indicates a corrupt, truncated, or inconsistently-indexed input .a/.rlib.

Source

Thrown at compiler/rustc_codegen_ssa/src/back/archive.rs:623

            }
            Some((names, rename_suffix))
        } else {
            None
        };

        let mut entries = Vec::new();

        for (entry_name, entry) in self.entries {
            let data: Box<dyn AsRef<[u8]>> = match entry.source {
                ArchiveEntrySource::Archive { archive_index, file_range } => {
                    let src_archive = &self.src_archives[archive_index];
                    let archive_data = &src_archive.1;
                    let start = file_range.0 as usize;
                    let end = start + file_range.1 as usize;
                    let Some(data) = archive_data.get(start..end) else {
                        return Err(io_error_context(
                            "invalid archive member",
                            io::Error::new(
                                io::ErrorKind::InvalidData,
                                format!(
                                    "archive member at offset {start} with size {} \
                                         exceeds archive size {} in `{}`",
                                    file_range.1,
                                    archive_data.len(),
                                    src_archive.0.display(),
                                ),
                            ),
                        ));
                    };

                    if entry.kind == ArchiveEntryKind::RustObj
                        && let Some(sym) = &symbols
                    {
                        Box::new(apply_edits(data, &sym.exported, sym.hide, rename.as_ref()))
                    } else {
                        Box::new(data)

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Run cargo clean (or remove target/) to delete the suspect archive and rebuild from source.
  2. Inspect the named archive with `ar t <path>` / `llvm-ar t <path>` to confirm it is malformed; if so, delete it.
  3. If the archive came from a crate dependency or vendored source, re-fetch/re-vendor it (rm -rf of the cached copy) to rule out a truncated download.
  4. Ensure no two build processes or editors are writing to the same target directory concurrently.
Defensive patterns

Strategy: validation

Validate before calling

use std::fs::File;
use std::io::{Read, Seek, SeekFrom};

fn archive_members_in_bounds(path: &std::path::Path) -> std::io::Result<bool> {
    let mut f = File::open(path)?;
    let total = f.metadata()?.len();
    let mut sig = [0u8; 8];
    if f.read_exact(&mut sig).is_err() || &sig != b"!<arch>\n" {
        return Ok(false);
    }
    loop {
        let mut hdr = [0u8; 60];
        if f.read_exact(&mut hdr).is_err() { break; }
        let size_field = std::str::from_utf8(&hdr[48..58])
            .unwrap_or("0").trim().parse::<u64>().unwrap_or(0);
        let start = f.stream_position()?;
        if start.saturating_add(size_field) > total { return Ok(false); }
        let advance = (size_field + 1) & !1; // 2-byte align
        f.seek(SeekFrom::Current(advance as i64))?;
    }
    Ok(true)
}

// caller: assert!(archive_members_in_bounds(Path::new("libfoo.a"))?);

Type guard

fn is_well_formed_archive(path: &std::path::Path) -> bool {
    archive_members_in_bounds(path).unwrap_or(false)
}

Try / catch

let s = String::from_utf8_lossy(&output.stderr);
if s.contains("exceeds archive size") {
    eprintln!("archive {} is corrupt; rebuilding", path.display());
    rebuild_archive(path)?;
}

Prevention

When it happens

Trigger: Triggered by ArchiveBuilder::write when iterating self.entries and an ArchiveEntrySource::Archive entry references a file_range that lies outside the mapped src_archive. Happens if an input rlib/static archive's header table disagrees with its actual byte length.

Common situations: A truncated or partially-written .rlib left behind by a killed/interrupted previous build. Disk corruption or a bad network filesystem serving the build cache. A malformed third-party .a static library with an ar index pointing past EOF. Concurrent writes to the same archive by two rustc invocations.

Related errors


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