denoland/deno · error

tar entry '{}' has invalid offset/size (offset={}, size={})

Error message

tar entry '{}' has invalid offset/size (offset={}, size={})

What it means

During tarball extraction, each regular-file entry's raw data offset and header size are combined with checked_add; if offset + size overflows usize, the size field must be an absurd value (near 2^64), which no legitimate archive has. The extractor rejects it as InvalidData with the entry path, offset and size. This is a hard integrity check against corrupt or deliberately crafted tar headers.

Source

Thrown at libs/npm_cache/tarball_extract.rs:408

        .filter(|path| path.starts_with(output_folder))
        .ok_or_else(|| {
          ExtractTarballError::NotInOutputDirectory(path.to_path_buf())
        })?
    };
    if !created_dirs.contains(dir_path) {
      created_dirs.insert(dir_path.to_path_buf());
      sys.fs_create_dir_all(dir_path)?;
    }

    let entry_type = entry.header().entry_type();
    match entry_type {
      EntryType::Regular => {
        let open_options = OpenOptions::new_write();
        let mut f = sys.fs_open(&absolute_path, &open_options)?;
        let data_offset = entry.raw_file_position() as usize;
        let size = entry.header().size()? as usize;
        let end = data_offset.checked_add(size).ok_or_else(|| {
          std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            format!(
              "tar entry '{}' has invalid offset/size (offset={}, size={})",
              absolute_path.display(),
              data_offset,
              size,
            ),
          )
        })?;
        let entry_data =
          tar_data.get(data_offset..end).ok_or_else(|| {
            std::io::Error::new(
              std::io::ErrorKind::UnexpectedEof,
              format!(
                "tar entry '{}' extends beyond archive (offset={}, size={}, archive_len={})",
                absolute_path.display(),
                data_offset,
                size,

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Delete the cached tarball for that package/version under the npm cache directory and retry the install so it re-downloads.
  2. Re-run with cache bypassed/reload (e.g. deno install with --reload) to force a fresh download.
  3. If it reproduces with a fresh download, verify the tarball shasum against the registry metadata and report the package/mirror — a persistently bad header means the source is corrupt or malicious.

Example fix

# before
deno install   # error: tar entry 'node_modules/foo/index.js' has invalid offset/size (offset=4096, size=18446744073709551615)

# after
rm -rf ~/.cache/deno/npm/registry.npmjs.org/foo
deno install --reload
Defensive patterns

Strategy: retry

Validate before calling

// verify a tarball before extraction: header sizes must fit in the buffer
fn tarball_headers_sane(tar_data: &[u8]) -> bool {
  let mut ar = tar::Archive::new(tar_data);
  ar.entries()
    .map(|entries| {
      entries
        .filter_map(|e| e.ok())
        .all(|e| e.raw_file_position() + e.header().size().unwrap_or(u64::MAX) as usize <= tar_data.len())
    })
    .unwrap_or(false)
}

Try / catch

match extract_tarball(&tar_data, &dest) {
  Ok(()) => {}
  Err(err) if err.kind() == std::io::ErrorKind::InvalidData => {
    // purge the corrupted cache entry and re-download once
    fs::remove_dir_all(&cached_pkg_dir).ok();
    let tar_data = client.download_again(&pkg).await?;
    extract_tarball(&tar_data, &dest)?;
  }
  Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Extracting an npm package tarball whose header size field is huge (e.g. 0xFFFFFFFFFFFFFFFF), typically because the cached .tgz is corrupted, was truncated and re-assembled wrongly, or was tampered with by a proxy/MITM.

Common situations: A corrupted entry in $DENO_DIR npm cache after a crash or disk-full event; a corporate proxy mangling registry responses; a compromised or typosquatted package on a mirror registry; bit rot on the cache volume.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/bf37ddaaee2f6a8e. Report an issue: GitHub.