jdx/mise · error · eyre::Report
remote action result does not match requested action
Error message
remote action result does not match requested action
What it means
After a successful GET, the client verifies the returned RemoteActionResult has version == 1 and an action field equal to the requested digest. A mismatch means the server answered with a record belonging to a different action or protocol generation — treated as corruption or cache poisoning rather than a hit. The error is deterministic, so neither the built-in retry loop nor a manual retry of the same request will help.
Source
Thrown at crates/mise-cache-core/src/lib.rs:378
.request(reqwest::Method::GET, url.clone(), ACTION_RESULT_MEDIA_TYPE)
.await?
.send()
.await?;
if response.status() == StatusCode::NOT_FOUND {
return Ok(None);
}
Ok(Some(
response
.error_for_status()?
.json::<RemoteActionResult>()
.await?,
))
})
.await?;
if let Some(result) = &result
&& (result.version != 1 || result.action != *action)
{
bail!("remote action result does not match requested action");
}
Ok(result)
}
pub async fn put_action_result(&self, result: &RemoteActionResult) -> Result<()> {
let url = self.action_result_endpoint(&result.action)?;
let body = serde_json::to_vec(result)?;
retry_async("PUT", &url, self.retries, || async {
let response = self
.request(reqwest::Method::PUT, url.clone(), ACTION_RESULT_MEDIA_TYPE)
.await?
.header(CONTENT_TYPE, ACTION_RESULT_MEDIA_TYPE)
.header(IF_NONE_MATCH, "*")
.body(body.clone())
.send()
.await?;
if response.status() != StatusCode::PRECONDITION_FAILED {
response.error_for_status()?;View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Treat the error as a cache miss: rebuild locally and optionally overwrite with put_action_result
- Verify the server keys action-results by the full algorithm/hash/size URL path and honors the namespace header
- Configure any proxy/CDN in front of the cache to vary on mise-cache-namespace and mise-cache-protocol
- Confirm client and server agree on PROTOCOL_VERSION (currently 1)
Example fix
// before
let result = client.get_action_result(&action).await?; // propagates mismatch error
// after: degrade to a miss on integrity failures
let result = match client.get_action_result(&action).await {
Ok(result) => result,
Err(report) if report.to_string().contains("does not match requested action") => None,
Err(report) => return Err(report),
}; Defensive patterns
Strategy: fallback
Try / catch
let result = match client.get_action_result(&action).await {
Ok(result) => result,
Err(report) if report.to_string().contains("does not match requested action") => {
// poisoned/corrupt entry: treat as a miss and rebuild
None
}
Err(report) => return Err(report),
}; Prevention
- Verify proxies vary on mise-cache-namespace and mise-cache-protocol headers
- Pin client and server to the same protocol version in CI
- Always structure cache reads so an integrity failure can degrade to a local rebuild
When it happens
Trigger: A cache server that ignores the mise-cache-namespace header or the algorithm/hash/size path and returns the wrong record; a reverse proxy serving a response cached under a different key; a server implementing a different protocol version (version != 1); a corrupted record stored under the right key.
Common situations: A shared reverse proxy in front of the cache that does not vary on the namespace or protocol headers; version skew after upgrading the cache server; multiple projects reusing one namespace on a server that keys only by hash.
Related errors
- remote cache action keys must use blake3
- remote action manifest ETag does not match its body
- remote cache blob failed digest verification
- remote action result is missing its output root
- remote cache directory graph contains a cycle
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/2d3764d970af5c4b.
Report an issue: GitHub.