jdx/mise · error
--cache-from must reference the same repository as the desti
Error message
--cache-from must reference the same repository as the destination (got {}/{}, destination is {}/{}) What it means
`--cache-from` names an already-pushed image whose layers push reuses (skipping re-upload). Because reused layer blobs are never uploaded, they must already live in the destination repository; a cache image from a different registry or repository would produce a manifest referencing blobs the destination does not have. mise therefore requires cache and destination to match on registry AND repository (tag may differ).
Source
Thrown at src/cli/oci/push.rs:173
/// Fetch the layer-reuse cache image: `--cache-from` if given, otherwise
/// the destination ref itself (the previously pushed image under this
/// tag). Returns `None` with `--no-cache`, when no previous image exists,
/// or when the lookup fails — a broken cache must never fail the push.
async fn fetch_layer_cache(&self) -> Result<Option<registry::RemoteImage>> {
if self.no_cache {
return Ok(None);
}
let cache_ref = self.cache_from.as_deref().unwrap_or(&self.reference);
if let Some(cache_from) = &self.cache_from {
// Reused layer blobs are never uploaded — they must already live
// in the destination repository, so a cache image from a
// different repo would produce a manifest referencing blobs the
// destination doesn't have.
let dest = registry::Reference::parse(&self.reference)?;
let cache = registry::Reference::parse(cache_from)?;
if dest.registry != cache.registry || dest.repository != cache.repository {
bail!(
"--cache-from must reference the same repository as the destination \
(got {}/{}, destination is {}/{})",
cache.registry,
cache.repository,
dest.registry,
dest.repository
);
}
}
match registry::fetch_remote_image(cache_ref).await {
Ok(remote) => {
if remote.is_none() {
debug!("no previous image at {cache_ref} — building all layers locally");
}
Ok(remote)
}
Err(e) => {
warn!("could not fetch layer cache from {cache_ref}: {e} — building all layers");View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Drop `--cache-from` entirely — push then defaults to using the destination ref as its own cache
- Point --cache-from at another tag in the SAME repo: `--cache-from ghcr.io/you/devenv:cache`
- If you need cross-repo caching, first `mise oci push` (or `skopeo copy`) the cache image into the destination repository
Example fix
# before mise oci push --cache-from ghcr.io/other/devenv:cache ghcr.io/you/devenv:tag # after mise oci push --cache-from ghcr.io/you/devenv:cache ghcr.io/you/devenv:tag
Defensive patterns
Strategy: validation
Validate before calling
# bash: cache ref must share registry/repo with destination
dest="ghcr.io/you/devenv:tag"
cache="${CACHE_FROM:-$dest}"
dest_rr="${dest%:*}"; cache_rr="${cache%:*}"
if [ "$dest_rr" != "$cache_rr" ]; then
cache="$dest_rr:cache" # fall back to same-repo cache tag
fi
mise oci push --cache-from "$cache" "$dest" Prevention
- Derive --cache-from from the destination string (same repo, ':cache' tag) instead of a separate variable
- When promoting across registries, explicitly push the cache image into the destination repo first
When it happens
Trigger: `mise oci push --cache-from ghcr.io/other/repo:cache ghcr.io/you/devenv:tag`, or mixing registries (`ghcr.io/you/devenv` vs `docker.io/you/devenv`). Note: when --cache-from is omitted, the destination itself is used as the cache ref, so this only fires with an explicit mismatched flag.
Common situations: Promoting images between namespaces or registries while keeping the old cache ref; CI copying a cache ref from another project's workflow; renaming the destination repo but not the cache variable.
Related errors
- push destination must be a fully-qualified reference (e.g. `
- fetching {manifest_url} failed: {}
- starting blob upload failed: {} {}{}
- blob chunk upload failed: {}{} {}
- blob upload failed: {}{} {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/cd0c05345272501c.
Report an issue: GitHub.