jdx/mise · error
remote cache blob pack content length metadata mismatch: exp
Error message
remote cache blob pack content length metadata mismatch: expected {}, decoded {} What it means
Thrown while validating a blob-pack download (crates/mise-cache-core/src/lib.rs:321): the response carried an X-style blob-pack metadata header-derived content_length (from the Content-Length-style optional header parsed in from_headers), and it does not equal decoded.framed_bytes — the number of bytes actually decoded from the framed pack stream (magic + per-blob records). This is an integrity check that the server's declared size matches the body it sent.
Source
Thrown at crates/mise-cache-core/src/lib.rs:321
blob_count: u64,
payload_bytes: u64,
framed_bytes: u64,
}
impl BlobPackResponseMetadata {
fn from_headers(headers: &HeaderMap) -> Result<Self> {
Ok(Self {
content_length: optional_u64_header(headers, CONTENT_LENGTH.as_str())?,
blob_count: optional_u64_header(headers, BLOB_PACK_BLOBS_HEADER)?,
payload_bytes: optional_u64_header(headers, BLOB_PACK_BYTES_HEADER)?,
})
}
fn validate(self, decoded: BlobPackResponseStats) -> Result<BlobPackResponseStats> {
if let Some(content_length) = self.content_length
&& content_length != decoded.framed_bytes
{
bail!(
"remote cache blob pack content length metadata mismatch: expected {}, decoded {}",
content_length,
decoded.framed_bytes
);
}
if let Some(blob_count) = self.blob_count
&& blob_count != decoded.blob_count
{
bail!(
"remote cache blob pack blob count metadata mismatch: expected {}, decoded {}",
blob_count,
decoded.blob_count
);
}
if let Some(payload_bytes) = self.payload_bytes
&& payload_bytes != decoded.payload_bytes
{
bail!(View on GitHub (pinned to 6f52dcdf99)
Solutions
- Retry the download once — a transient truncation (dropped connection mid-body) can produce this
- Disable blob packs for this remote (the client tracks blob_packs_disabled; falling back to per-blob GETs sidesteps pack metadata entirely) and verify blobs download individually
- Check any proxy/CDN between client and cache for body-rewriting (compression, chunked re-framing); bypass it or exclude the pack media type application/vnd.mise.cache-blob-pack.v1
- If you operate the server, ensure the metadata headers describe the exact framed payload emitted
Defensive patterns
Strategy: retry
Try / catch
match client.get_blob_pack(&digests, &staging).await {
Err(e) if e.to_string().contains("content length metadata mismatch") => {
client.disable_blob_packs();
for d in &digests { let _ = client.get_blob(d, media_type).await?; } // per-blob fallback
}
other => other?,
} Prevention
- Exclude application/vnd.mise.cache-blob-pack.v1 responses from proxy compression/re-framing
- Retry pack downloads once before falling back — truncation is often transient
- Monitor mismatch rate per server; a persistent offender is a server bug, not a client problem
When it happens
Trigger: Calling the blob-pack download path (decode_blob_pack at lib.rs:899, fed by get_blob_pack) where the server advertises a content length in its headers that differs from the actual framed stream size — e.g. a proxy rewrote/truncated the body, the server has a bug computing the header, or a chunked/encoded response made the header stale.
Common situations: A corporate proxy or CDN re-encoding responses (gzip stripped or applied) so Content-Length no longer matches the decoded bytes; a misbehaving or incompatible remote cache server version; a race where the pack was regenerated server-side between header emission and body streaming.
Related errors
- remote cache blob pack payload byte metadata mismatch: expec
- remote cache blob pack blob count metadata mismatch: expecte
- remote cache blob pack has invalid magic
- remote cache blob pack has an invalid digest algorithm
- remote cache blob packs require a positive max_pack_bytes li
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/80a47b48f1b97c34.
Report an issue: GitHub.