rust-lang/cargo · error · anyhow::Error
cache expected 4 bytes for index schema version
Error message
cache expected 4 bytes for index schema version
What it means
When parsing the on-disk `SummariesCache` for a crate (src/sources/registry/index/cache.rs:165), Cargo reads a 1-byte version header then expects at least 4 more bytes encoding the little-endian `u32` index schema version. If the file is truncated to fewer than 5 bytes total (`rest.get(..4)` is `None`), it bails. This indicates a corrupt or partially-written cache entry.
Source
Thrown at src/sources/registry/index/cache.rs:175
pub versions: Vec<(Version, &'a [u8])>,
/// For cache invalidation, we tracks the index file version to determine
/// when to regenerate the cache itself.
pub index_version: &'a str,
}
impl<'a> SummariesCache<'a> {
/// Deserializes an on-disk cache.
pub fn parse(data: &'a [u8]) -> CargoResult<SummariesCache<'a>> {
// NB: keep this method in sync with `serialize` below
let (first_byte, rest) = data
.split_first()
.ok_or_else(|| anyhow::format_err!("malformed cache"))?;
if *first_byte != CURRENT_CACHE_VERSION {
bail!("looks like a different Cargo's cache, bailing out");
}
let index_v_bytes = rest
.get(..4)
.ok_or_else(|| anyhow::anyhow!("cache expected 4 bytes for index schema version"))?;
let index_v = u32::from_le_bytes(index_v_bytes.try_into().unwrap());
if index_v != INDEX_V_MAX {
bail!(
"index schema version {index_v} doesn't match the version I know ({INDEX_V_MAX})",
);
}
let rest = &rest[4..];
let mut iter = split(rest, 0);
let last_index_update = if let Some(update) = iter.next() {
str::from_utf8(update)?
} else {
bail!("malformed file");
};
let mut ret = SummariesCache::default();
ret.index_version = last_index_update;
while let Some(version) = iter.next() {
let version = str::from_utf8(version)?;View on GitHub (pinned to 0e07a15537)
Solutions
- Clear the affected cache: `rm -rf ~/.cargo/registry/index/*/.cache/` and let Cargo regenerate it.
- If it recurs, check for disk-full conditions, antivirus, or cloud-sync tools touching `~/.cargo`.
- Run `cargo cache --autoclean` (if cargo-cache is installed) or a full `cargo clean`.
Example fix
# before: corrupt cache blocks every build rm -rf ~/.cargo/registry/index/*/.cache/ cargo fetch
Defensive patterns
Strategy: fallback
Validate before calling
// Before trusting a cache file, sanity-check its length.
fn cache_looks_complete(data: &[u8]) -> bool {
data.len() >= 5 // 1 version byte + 4 schema-version bytes
} Try / catch
// On parse failure, delete and regenerate rather than crash.
match SummariesCache::parse(&data) {
Ok(c) => c,
Err(_) => { fs::remove_file(&cache_path).ok(); /* force refetch */ bail!("cache corrupt, removed"); }
} Prevention
- Treat cache parse failures as recoverable: evict and refetch.
- Keep cloud-sync/antivirus tools away from `~/.cargo`.
- Ensure writes have enough disk space; avoid SIGKILL mid-build.
When it happens
Trigger: A cache file under `~/.cargo/registry/index/<reg>/.cache/` that was truncated by a crash/power loss mid-write, a filesystem with 512-byte sector corruption, or an external tool that emptied/truncated the file. Reached on any operation that loads a cached crate summary.
Common situations: Build interrupted by SIGKILL/OOM while Cargo was rewriting the cache; antivirus or sync tools (Dropbox/OneDrive) truncating files in `~/.cargo`; disk full at write time; upgrading Cargo across a cache-format change with a half-written file.
Related errors
- registry said cache valid when no cache exists
- path `{}` is not a blob in the git repo
- invalid tarball downloaded, contains a file at {entry_path:?
- invalid tarball downloaded, contains an entry at {entry_path
- multiple registries are configured with the same index url '
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/eb3775ea10661801.json.
Report an issue: GitHub.