sxyazi/yazi · error · io::Error
Cache stamp does not match entry
Error message
Cache stamp does not match entry
What it means
Returned by Stamp::resolve when the stamp file at dir/key decodes fine, but re-hashing the resolved URL (hash_u128_str) does not equal the encoded key. The stamp therefore points at an entry that does not match the requested cache key — the cache lookup is inconsistent or stale.
Source
Thrown at yazi-vfs/src/stamp.rs:48
pub async fn resolve<U, S>(dir: U, key: S) -> io::Result<UrlBuf>
where
U: AsUrl,
S: AsStrand,
{
let dir = dir.as_url();
let key = key.as_strand();
let mut path =
dir.auth().stamp_root().ok_or_else(|| io::Error::other("Cannot determine stamp root"))?;
path.push(key.as_os()?);
let stamp = Self::read_at(&path).await?;
let name = StrandCow::with(dir.loc().kind(), stamp.name()).map_err(io::Error::other)?;
let url = dir.try_join(name)?;
if url.hash_u128_str(&mut [0; Self::SIG_LEN]).as_bytes() != key.encoded_bytes() {
return Err(io::Error::new(io::ErrorKind::InvalidData, "Cache stamp does not match entry"));
}
Ok(url)
}
pub async fn write(cha: Cha, url: Url<'_>) -> io::Result<()> {
let path = url.stamp_entry().ok_or_else(|| io::Error::other("Cannot determine cache stamp"))?;
let data = Self::encode(cha, url)?;
Local::regular(&path)
.write(data)
.await
.map_err(|e| io::Error::new(e.kind(), format!("Cannot write cache stamp: {e}")))
}
fn encode(cha: Cha, url: Url) -> io::Result<Vec<u8>> {
let name = url.name().ok_or_else(|| io::Error::other("URL has no filename"))?;
View on GitHub (pinned to 8ebf930f17)
Solutions
- Treat as a cache miss: delete the mismatched stamp and re-fetch/re-write via Stamp::write with the correct entry
- Ensure resolve is called with the same dir and key pair used when the stamp was written
- Clear the cache directory if entries were created by a different Yazi version
Example fix
// before
let url = Stamp::resolve(dir, key).await?;
// after
let url = Stamp::resolve(dir, key).await
.or_else(|e| if e.kind() == io::ErrorKind::InvalidData { cache_miss(dir, key) } else { Err(e) })
.await?; Defensive patterns
Strategy: validation
Validate before calling
// verify the stamp belongs to this key before trusting it
let url = dir.try_join(name)?;
let mut sig = [0u8; 16];
if url.hash_u128_str(&mut sig).as_bytes() != key.encoded_bytes() {
// mismatch: treat as cache miss
} Type guard
fn stamp_matches_key(stamp: &Stamp, key: &CacheKey) -> bool {
stamp.0.len() > Stamp::SIG_LEN && !stamp.name().is_empty()
} Try / catch
match Stamp::resolve(dir, key).await {
Ok(url) => url,
Err(e) if e.kind() == io::ErrorKind::InvalidData => cache_miss_fallback(),
Err(e) => return Err(e),
} Prevention
- Always pair resolve with the exact (dir, key) used at write time
- Do not share one cache directory across different remotes or versions
- Delete stale stamps when their source entry is renamed or removed
When it happens
Trigger: Calling Stamp::resolve(dir, key) where the stamp's recorded name joins to a URL whose u128 hash differs from key.encoded_bytes(): key collision handling, a stamp written for a different source entry, or a changed hashing input (e.g. remote metadata changed identity).
Common situations: Cache directory shared or reused across remotes/versions; a stamp file left behind after the source entry was renamed or replaced; hand-edited or copied cache entries.
Related errors
- Cache stamp does not match target
- Remote file has changed since last download
- Invalid cache stamp
- Cannot read cache stamp: {e}
- Cannot parse cache stamp: {e}
AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02).
Data as JSON: /api/errors/c1df7dc706448b79.
Report an issue: GitHub.