sxyazi/yazi · error · io::Error
Cache stamp does not match target
Error message
Cache stamp does not match target
What it means
Returned by Stamp::validate when the stamp's recorded filename differs from the target URL's name. It is an InvalidData error indicating the cached stamp belongs to a different file than the URL being validated, so the cache entry must not be trusted.
Solutions
- Rewrite the stamp for the current URL via Stamp::write to resynchronize name and signature
- Verify the stamp file being validated is the one derived from this URL (stamp_entry)
- If the remote renamed the file, refresh the cache entry under the new name
Example fix
// before
stamp.validate(cha, url)?;
// after
if let Err(e) = stamp.validate(cha, url) {
if e.kind() == io::ErrorKind::InvalidData { Stamp::write(cha, url.clone()).await?; }
else { return Err(e); }
} Defensive patterns
Strategy: validation
Validate before calling
if let Some(name) = url.name() {
// name must equal the stamp's recorded name before validating
if stamp.name() != name.encoded_bytes() { /* regenerate stamp */ }
} Type guard
fn stamp_targets(stamp: &Stamp, url: &Url) -> bool {
url.name().map(|n| stamp.name() == n.encoded_bytes()).unwrap_or(false)
} Try / catch
match stamp.validate(cha, url.clone()) {
Ok(()) => (),
Err(e) if e.kind() == io::ErrorKind::InvalidData => Stamp::write(cha, url).await?,
Err(e) => return Err(e),
} Prevention
- Write a fresh stamp immediately after every download
- Never reuse a stamp file across different URLs
- Look up the stamp strictly via url.stamp_entry()
When it happens
Trigger: Calling stamp.validate(cha, url) where url.name() is None would already error earlier; the specific 'does not match target' fires when self.name() != name.encoded_bytes() — i.e., the stamp was written for a differently-named file than the URL supplied.
Common situations: Reusing a cached stamp across renamed files; mixing up cache entries after a remote rename; a bug where the wrong stamp file is looked up for a URL.
Related errors
- Cache stamp does not match entry
- Invalid cache stamp
- Remote file has changed since last download
- Cannot parse cache stamp
- Cannot read cache stamp
AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02).
Data as JSON: /api/errors/80903ebffb7ccc8e.
Report an issue: GitHub.
Appendix: source
Thrown at yazi-vfs/src/stamp.rs:77
.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"))?;
let mut buf = Vec::with_capacity(Self::SIG_LEN + name.len());
buf.extend_from_slice(cha.hash_u128_str(&mut [0; Self::SIG_LEN]).as_bytes());
buf.extend_from_slice(name.encoded_bytes());
Ok(buf)
}
pub fn validate(&self, cha: Cha, url: Url) -> io::Result<()> {
let name = url.name().ok_or_else(|| io::Error::other("URL has no filename"))?;
if self.name() != name.encoded_bytes() {
return Err(io::Error::new(io::ErrorKind::InvalidData, "Cache stamp does not match target"));
}
if self.sig() != cha.hash_u128_str(&mut [0; Self::SIG_LEN]) {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Remote file has changed since last download",
));
}
Ok(())
}
#[inline]
pub fn sig(&self) -> &str { unsafe { str::from_utf8_unchecked(&self.0[..Self::SIG_LEN]) } }
#[inline]
fn name(&self) -> &[u8] { &self.0[Self::SIG_LEN..] }
}
View on GitHub (pinned to 8ebf930f17)