rust-lang/cargo · error
invalid tarball downloaded, contains a file at
Error message
invalid tarball downloaded, contains a file at {entry_path:?} which isn't under {prefix:?} What it means
While unpacking a `.crate` tarball, Cargo requires every entry's path to be under the package prefix (`<pkg>-<ver>/`). If `entry_path.strip_prefix(prefix)` fails, the tarball contains a file outside the expected root — a path-traversal or malformed-tarball safety violation. Cargo blocks it to prevent overwriting other crates' source.
Solutions
- Re-download the official `.crate` from crates.io or the original registry to replace a corrupt/repackaged one.
- If you publish crates, ensure packaging uses `cargo package` which emits the correct root prefix.
- Clear cache: `rm ~/.cargo/registry/cache/<index>/<pkg>-<ver>.crate` and refetch.
- Audit the registry mirror — reject re-packaged tarballs lacking the `<pkg>-<ver>/` prefix.
Example fix
# before: tarball with flat (non-prefixed) layout $ tar tf serde-1.0.0.crate Cargo.toml src/lib.rs # after: properly packaged (re-fetch from trusted registry) $ tar tf serde-1.0.0.crate serde-1.0.0/Cargo.toml serde-1.0.0/src/lib.rs
Defensive patterns
Strategy: validation
Validate before calling
fn validate_tarball_prefix(tar: &tar::Archive<std::fs::File>, expected_prefix: &str) -> Result<(), anyhow::Error> {
for entry in tar.entries()? {
let e = entry?;
let p = e.path()?;
if !p.starts_with(expected_prefix) {
anyhow::bail!("entry outside prefix: {:?}", p);
}
}
Ok(())
} Type guard
fn tarball_all_under_prefix(path: &std::path::Path, prefix: &str) -> bool {
let f = std::fs::File::open(path).ok();
f.and_then(|f| tar::Archive::new(f).entries().ok()).map_or(false, |mut es| {
es.by_ref().all(|e| e.map_or(false, |e| e.path().map_or(false, |p| p.starts_with(prefix))))
})
} Try / catch
if entry_path.strip_prefix(prefix).is_err() {
// do not bail hard if you can re-fetch: replace the crate and retry
refetch_crate(pkg)?;
return unpack(...);
} Prevention
- Only consume `.crate` files from trusted registries.
- Package crates with `cargo package` (correct root prefix).
- Reject re-packaged tarballs in private registry mirrors.
- Audit uploaded tarballs for path-traversal entries before publishing.
When it happens
Trigger: `unpack()` iterates tar entries; an entry path does not start with the package prefix. Caused by a tarball built with absolute paths, `..` segments, or missing the `<pkg>-<ver>/` root — i.e. a non-conformant or malicious `.crate` file.
Common situations: A hand-built / third-party-packaged `.crate` that omits the conventional root directory; a tampered or corrupted tarball; an old or non-standard tool producing flat tarballs; a registry mirror that re-packaged crates incorrectly.
Related errors
- invalid tarball downloaded, contains an entry at
- failed to verify the checksum of
- failed to verify the checksum of
- path ` ` is not a blob in the git repo
- unable to read .cargo-ok file at
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/c0662a46180a7ac3.
Report an issue: GitHub.
Appendix: source
Thrown at src/sources/registry/mod.rs:999
for entry in tar.entries()? {
let mut entry = entry.context("failed to iterate over archive")?;
let entry_path = entry
.path()
.context("failed to read entry path")?
.into_owned();
if let Ok(path) = entry_path.strip_prefix(prefix) {
if !include(path) {
continue;
}
} else {
// We're going to unpack this tarball into the global source
// directory, but we want to make sure that it doesn't accidentally
// (or maliciously) overwrite source code from other crates. Cargo
// itself should never generate a tarball that hits this error, and
// crates.io should also block uploads with these sorts of tarballs,
// but be extra sure by adding a check here as well.
anyhow::bail!(
"invalid tarball downloaded, contains \
a file at {entry_path:?} which isn't under {prefix:?}",
)
}
// Prevent unpacking symlinks and other unexpected entry types
match entry.header().entry_type() {
EntryType::Regular | EntryType::Directory => {}
t => anyhow::bail!(
"invalid tarball downloaded, contains an entry at {entry_path:?} with invalid type {t:?}",
),
}
// Prevent unpacking the lockfile from the crate itself.
if entry_path
.file_name()
.map_or(false, |p| p == PACKAGE_SOURCE_LOCK)
{View on GitHub (pinned to 98a09e7e7d)