sxyazi/yazi · warning · io::Error

Invalid cache stamp

Error message

Invalid cache stamp

What it means

Produced by TryFrom<Vec<u8>> for Stamp with ErrorKind::InvalidData when a stamp file's bytes cannot be a stamp: the payload is shorter than SIG_LEN (26 bytes) or the filename segment after the signature is empty (split_at_checked + filter(|(_, n)| !n.is_empty())). It surfaces through Stamp::read/read_at wrapped as "Cannot parse cache stamp: Invalid cache stamp".

Source

Thrown at yazi-vfs/src/stamp.rs:103

		}
		Ok(())
	}

	#[inline]
	pub fn sig(&self) -> &str { unsafe { str::from_utf8_unchecked(&self.0[..Self::SIG_LEN]) } }

	#[inline]
	pub fn name(&self) -> &[u8] { &self.0[Self::SIG_LEN..] }
}

impl TryFrom<Vec<u8>> for Stamp {
	type Error = io::Error;

	fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
		let (sig, _) = value
			.split_at_checked(Self::SIG_LEN)
			.filter(|(_, n)| !n.is_empty())
			.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Invalid cache stamp"))?;

		str::from_utf8(sig).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
		Ok(Self(value))
	}
}

View on GitHub (pinned to 94abcfa92f)

Solutions

  1. Delete the offending stamp file (<tmp>/yazi-<uid>/<kind>_<scheme>_<hash>/%stamp/<urlhash>) so yazi recreates it on the next download
  2. Clear the whole <tmp>/yazi-<uid> tree after upgrading yazi to discard incompatible stamp formats
  3. If it recurs with no upgrade or crash, find what else writes into the temp dir (collision or tampering) and exclude it

Example fix

// before
let stamp = Stamp::read(&url).await?; // InvalidData aborts the lookup

// after
let stamp = match Stamp::read(&url).await {
    Ok(s) => s,
    Err(e) if e.kind() == io::ErrorKind::InvalidData => return refetch(url).await, // corrupt stamp == cache miss
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: validation

Validate before calling

// a well-formed stamp is SIG_LEN (26) signature bytes + a non-empty name
let meta = std::fs::metadata(&stamp_path)?;
if meta.len() < 27 {
    let _ = std::fs::remove_file(&stamp_path); // corrupt: delete and take the cache-miss path
}

Try / catch

let stamp = match Stamp::read(&url).await {
    Ok(s) => s,
    Err(e) if e.kind() == io::ErrorKind::InvalidData => return refetch(url).await, // corrupt stamp == miss
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Stamp::read(url) opens an existing stamp file that is empty or truncated — a hard kill mid-write, a disk cleaner truncating files — or a stamp written by an older yazi format with a different SIG_LEN, or a foreign file that landed on the hashed stamp path.

Common situations: kill -9 of yazi during a stamp write; tmpreaper/systemd-tmpfiles interfering with files under <tmp>/yazi-<uid>; switching between yazi versions that share the same temp dir with different stamp layouts.

Related errors


AI-assisted analysis of sxyazi/yazi@94abcfa92f (2026-08-16). Data as JSON: /api/errors/4318f0dbc6b047e3. Report an issue: GitHub.