jdx/mise · error

task cache artifact checksum mismatch

Error message

task cache artifact checksum mismatch

What it means

verify_artifact_checksum recomputes the artifact checksum from the manifest roots and the archive and compares it to manifest.artifact_checksum. A mismatch means the archived bytes no longer match what was recorded at save time — corruption, tampering, or a partially overwritten archive — so the cache refuses to restore untrusted content.

Source

Thrown at src/task/task_cache.rs:941

        execution_duration_ns: manifest.execution_duration_ns,
        archive_checksum,
    };
    let encoded = serde_json::to_string(&material)?;
    Ok(format!("blake3:{}", hash::hash_blake3_to_str(&encoded)))
}

fn verify_artifact_checksum(manifest: &CacheManifest, archive_path: Option<&Path>) -> Result<()> {
    let Some(expected) = &manifest.artifact_checksum else {
        return Ok(());
    };
    let archive_path = if manifest.roots.is_empty() {
        None
    } else {
        Some(archive_path.ok_or_else(|| eyre!("task cache archive is missing"))?)
    };
    let actual = calculate_artifact_checksum(manifest, archive_path)?;
    if actual != *expected {
        bail!("task cache artifact checksum mismatch");
    }
    Ok(())
}

pub(crate) fn task_cache_entries(task: &Task, root: &Path) -> Result<Vec<TaskCacheEntry>> {
    Settings::get().ensure_experimental("task artifact caching")?;
    let cache_dir = task_cache_dir();
    if !cache_dir.is_dir() {
        return Ok(Vec::new());
    }
    let identity = task_cache_identity(task, root);
    let current_key = file::read_to_string(task_cache_state_path(task, root))
        .ok()
        .map(|key| key.trim().to_string());
    let mut entries = Vec::new();
    for entry in fs::read_dir(&cache_dir)? {
        let entry = entry?;
        let manifest_path = entry.path();

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Delete the affected entry (or wipe the cache dir) and re-run to regenerate the artifact
  2. If using a remote store, verify its integrity/headers and check for concurrent writers on the same key
  3. Ensure the cache volume is writable and stable (no disk-full, no flaky mounts)
  4. Treat unexpected checksum failures on a private cache as possible tampering and rotate the cache

Example fix

# shell
rm -rf "${XDG_CACHE_HOME:-$HOME/.cache}/task-artifacts/v2/<entry-dir>
mise run build
Defensive patterns

Strategy: fallback

Validate before calling

# recompute and compare if you mirror caches externally
cd /path/to/extract && find . -type f | sort | xargs sha256sum | sha256sum

Try / catch

Delete the entry, re-run uncached to regenerate, and if failures repeat on a private single-writer cache, investigate storage/bit-rot; on shared caches, treat as tampering and rotate.

Prevention

When it happens

Trigger: Restoring an entry whose archive was modified after save: bit rot, a concurrent writer replacing the artifact, a remote cache proxy serving truncated/mangled bodies, or manual edits inside the cache. The check runs during both restore paths via verify_artifact_checksum(manifest, archive_path).

Common situations: Shared remote cache with unreliable storage; NFS muting fsync semantics; two CI jobs racing on the same key; security-sensitive setups where this bail is the tamper alarm.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/7ea53eb97bb11689. Report an issue: GitHub.