rust-lang/cargo · critical · anyhow::Error
invalid tarball downloaded, contains a file at {entry_path:?
Error message
invalid tarball downloaded, contains a file at {entry_path:?} which isn't under {prefix:?} What it means
While unpacking a downloaded `.crate` tarball (src/sources/registry/mod.rs:977), Cargo requires every archive entry's path to live under the expected package prefix (`<name>-<version>/`). An entry that doesn't `strip_prefix(prefix)` is rejected as an invalid/malicious tarball — this is the path-traversal / wrong-packaging guard. The comment notes Cargo itself and crates.io should never produce such tarballs; this check is a belt-and-suspenders defense.
Source
Thrown at src/sources/registry/mod.rs:988
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 0e07a15537)
Solutions
- Re-create/re-download the tarball: clear `~/.cargo/registry/cache/<reg>/<pkg>-<ver>.crate` and refetch.
- If you publish/maintain the crate, ensure your packaging produces entries under `<name>-<version>/` (standard `cargo package` output).
- Inspect the tarball manually (`tar -tvf <file>.crate`) to see the offending entry path and fix the upstream packaging.
- Treat as a potential supply-chain attack if the registry is untrusted — stop using that registry.
Defensive patterns
Strategy: validation
Validate before calling
// Validate a tarball before unpacking: every entry must live under the prefix.
fn tarball_has_valid_prefix<R: Read>(tar: &mut tar::Archive<R>, prefix: &str) -> bool {
for e in tar.entries().ok().into_iter().flatten() {
if !e.path().ok().map_or(false, |p| p.starts_with(prefix)) { return false; }
}
true
} Type guard
pub fn entry_under_prefix(p: &std::path::Path, prefix: &str) -> bool {
p.strip_prefix(prefix).is_ok()
} Prevention
- Always package crates with `cargo package`, which guarantees the `<name>-<ver>/` prefix.
- Refuse to consume tarballs that fail the prefix check — treat as supply-chain risk.
- Verify downloaded `.crate` checksums before unpacking (Cargo does this upstream).
When it happens
Trigger: A tarball containing an entry whose path doesn't start with `<name>-<version>/` — e.g. an absolute path (`/etc/...`), a `../` traversal, or a flat entry with no prefix. Produced by a buggy custom registry/packaging tool, a corrupted download, or an attacker-controlled tarball.
Common situations: A private registry whose packaging tool doesn't prepend the `name-version/` prefix; a corrupted/garbled download that scrambled entry paths; a malicious substitute registry. Should never happen for crates.io-published crates.
Related errors
- invalid tarball downloaded, contains an entry at {entry_path
- failed to verify the checksum of `{}`
- path `{}` is not a blob in the git repo
- cache expected 4 bytes for index schema version
- registry said cache valid when no cache exists
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/c0662a46180a7ac3.json.
Report an issue: GitHub.