jdx/mise · error

invalid remote task cache key

Error message

invalid remote task cache key

What it means

Remote task cache keys must be exactly 64 lowercase hex characters (a sha-256 digest). validate_remote_key enforces length 64 and restricts bytes to 0-9 and a-f. Any other string — uppercase hex, truncated hashes, path-like or free-form keys — is rejected before it can be used as a remote cache key.

Source

Thrown at src/task/task_cache_store.rs:840

            }
            RestoredNode::Symlink { target, .. } => {
                header.set_size(0);
                archive.append_link(&mut header, path, target)?;
            }
        }
    }
    let encoder = archive.into_inner()?;
    encoder.finish()?;
    Ok(archive_file)
}

fn validate_remote_key(key: &str) -> Result<()> {
    if key.len() != 64
        || !key
            .bytes()
            .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
    {
        bail!("invalid remote task cache key");
    }
    Ok(())
}

pub(crate) struct LocalTaskCacheStore {
    root: PathBuf,
}

impl LocalTaskCacheStore {
    pub(crate) fn new(root: PathBuf) -> Self {
        Self { root }
    }

    fn paths(&self, key: &str) -> (PathBuf, PathBuf) {
        (
            self.root.join(format!("{key}.tar.zst")),
            self.root.join(format!("{key}.json")),
        )

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Hash the cache inputs with sha-256 and hex-encode lowercase before passing the key
  2. Lowercase any uppercase hex digests: key.to_ascii_lowercase()
  3. Use the full 64-character digest — do not truncate or prefix it
  4. If using a custom backend, ensure it derives 64-char lowercase hex keys

Example fix

// before
let key = format!("cache-{}", input_hash_hex.to_uppercase());
// after
use sha2::{Digest, Sha256};
let mut h = Sha256::new();
h.update(cache_inputs);
let key = hex::encode(h.finalize()); // 64 lowercase hex chars
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_remote_key(key: &str) -> bool {
    key.len() == 64
        && key.bytes().all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b))
}

Try / catch

let key = compute_cache_key(inputs);
if !is_valid_remote_key(&key) {
    return Err(anyhow!("cache key must be 64-char lowercase hex, got {key:?}"));
}
store.get(&key).await?

Prevention

When it happens

Trigger: A remote cache store operation receives a key that is not 64-char lowercase hex: an uppercase digest, a truncated/prefixed hash, a human-readable key, or a key containing '/', ':', or whitespace.

Common situations: Hand-rolled cache keys instead of hashing inputs; a hex encoder emitting uppercase; truncating digests; a custom backend that uses non-digest keys.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/52136fa4e88eac4c. Report an issue: GitHub.