jdx/mise · error · eyre::Report

unsupported remote cache digest algorithm

Error message

unsupported remote cache digest algorithm

What it means

CacheDigest::validate() only accepts the exact, case-sensitive algorithm strings "blake3" and "sha256". This error fires when any digest handed to the remote cache or local CAS (blobs, action results, manifests) declares a different algorithm name. It is the first guard in validate(), so it triggers before the hash-format check and a well-formed hash never masks a bad algorithm.

Source

Thrown at crates/mise-cache-core/src/lib.rs:116

            algorithm: "blake3".into(),
            hash: blake3::hash(bytes).to_hex().to_string(),
            size: bytes.len() as u64,
        }
    }

    /// Hash a file while counting the bytes read in the same streaming pass.
    pub fn blake3_file(path: &Path) -> Result<Self> {
        let (hash, size) = hash_file_blake3(path)?;
        Ok(Self {
            algorithm: "blake3".into(),
            hash,
            size,
        })
    }

    pub fn validate(&self) -> Result<()> {
        if self.algorithm != "blake3" && self.algorithm != "sha256" {
            bail!("unsupported remote cache digest algorithm");
        }
        if self.hash.len() != 64
            || !self
                .hash
                .bytes()
                .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
        {
            bail!("invalid remote cache digest");
        }
        Ok(())
    }

    pub fn matches_bytes(&self, bytes: &[u8]) -> Result<bool> {
        self.validate()?;
        if self.size != bytes.len() as u64 {
            return Ok(false);
        }
        let hash = match self.algorithm.as_str() {

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Set algorithm to the exact lowercase string "blake3" or "sha256" — the comparison is case-sensitive
  2. Prefer the constructors CacheDigest::blake3(bytes) or CacheDigest::blake3_file(path), which always set the algorithm correctly
  3. If the digest comes from serialized data, normalize the algorithm to lowercase and confirm it is one of the two supported names before use
  4. Call digest.validate() as soon as a digest arrives from an external source so the failure happens at the boundary with a clear error

Example fix

// before
let digest = CacheDigest { algorithm: "SHA256".into(), hash, size };
client.get_blob(&digest, media).await?;

// after
let digest = CacheDigest { algorithm: "sha256".into(), hash: hash.to_lowercase(), size };
client.get_blob(&digest, media).await?;

// best: never assemble by hand
let digest = CacheDigest::blake3(&bytes);
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_supported_digest(digest: &CacheDigest) -> eyre::Result<()> {
    if !matches!(digest.algorithm.as_str(), "blake3" | "sha256") {
        eyre::bail!("unsupported digest algorithm {:?}", digest.algorithm);
    }
    digest.validate()
}
// run before any RemoteCacheClient / LocalCas / LocalActionCache call

Type guard

fn has_supported_algorithm(digest: &CacheDigest) -> bool {
    matches!(digest.algorithm.as_str(), "blake3" | "sha256")
}

Prevention

When it happens

Trigger: Manually constructing a CacheDigest with algorithm set to "SHA256", "Blake3", "blake2b", "" (or a typo) and passing it to RemoteCacheClient::get_blob/get_action_result/get_action_manifest, LocalCas::path_for/find/store_bytes/store_file, LocalActionCache::find/store, or calling digest.matches_bytes()/matches_file(). Also thrown when a CacheDigest deserialized from JSON (RemoteActionResult, CacheDirectory nodes) carries a renamed or re-cased algorithm field.

Common situations: Interoperating with manifests or servers written by a different tool version that uses different algorithm names; a JSON processing layer that uppercases strings; hand-built digests in test fixtures; digests copied from a sha1/sha512-based system.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/7b8b3404bd7064d4. Report an issue: GitHub.