{"record":{"id":"cd0c05345272501c","repo":"jdx/mise","slug":"cache-from-must-reference-the-same-repository-as","errorCode":null,"errorMessage":"--cache-from must reference the same repository as the destination (got {}/{}, destination is {}/{})","messagePattern":"--cache-from must reference the same repository as the destination \\(got (.+?)/(.+?), destination is (.+?)/(.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/oci/push.rs","lineNumber":177,"sourceCode":"\n    /// Fetch the layer-reuse cache image: `--cache-from` if given, otherwise\n    /// the destination ref itself (the previously pushed image under this\n    /// tag). Returns `None` with `--no-cache`, when no previous image exists,\n    /// or when the lookup fails — a broken cache must never fail the push.\n    async fn fetch_layer_cache(&self) -> Result<Option<registry::RemoteImage>> {\n        if self.no_cache {\n            return Ok(None);\n        }\n        let cache_ref = self.cache_from.as_deref().unwrap_or(&self.reference);\n        if let Some(cache_from) = &self.cache_from {\n            // Reused layer blobs are never uploaded — they must already live\n            // in the destination repository, so a cache image from a\n            // different repo would produce a manifest referencing blobs the\n            // destination doesn't have.\n            let dest = registry::Reference::parse(&self.reference)?;\n            let cache = registry::Reference::parse(cache_from)?;\n            if !dest.same_repository(&cache) {\n                bail!(\n                    \"--cache-from must reference the same repository as the destination \\\n                     (got {}/{}, destination is {}/{})\",\n                    cache.registry,\n                    cache.repository,\n                    dest.registry,\n                    dest.repository\n                );\n            }\n        }\n        match registry::fetch_remote_image(cache_ref).await {\n            Ok(remote) => {\n                if remote.is_none() {\n                    debug!(\"no previous image at {cache_ref} — building all layers locally\");\n                }\n                Ok(remote)\n            }\n            Err(e) => {\n                warn!(\"could not fetch layer cache from {cache_ref}: {e} — building all layers\");","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/oci/push.rs#L159-L195","documentation":"`mise oci push --cache-from` requires the cache image to live in the same registry/repository as the push destination. Cross-repository cache images would yield manifests referencing blobs the destination registry doesn't have, so mise rejects the mismatch by comparing parsed References with same_repository().","triggerScenarios":"Running a push (fetch_layer_cache called from BuildOptions) where the parsed --cache-from Reference has a different registry or repository than the --reference destination.","commonSituations":"Caching from a public mirror (docker.io/library/...) while pushing to ghcr.io, or moving the image to a new namespace but keeping the old --cache-from value.","solutions":["Change --cache-from to an image in the same registry/repository as the destination (e.g. an earlier tag)","Update --reference to the same repository as the cache image","Drop --cache-from and build without layer cache"],"exampleFix":"// before\nmise oci push --cache-from ghcr.io/old/app:cache ghcr.io/new/app:tag\n// after\nmise oci push --cache-from ghcr.io/new/app:cache ghcr.io/new/app:tag","handlingStrategy":"validation","validationCode":"[[ \"$cache_from\" == \"$(dirname \"$dest_ref\")\"* ]] || echo \"cache-from must share the destination repository\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive --cache-from from the destination reference (same registry/repo, different tag)","Update cache references whenever the image moves registries or namespaces","Omit --cache-from rather than guessing a cross-repo cache image"],"tags":["oci","cache","registry"],"backgroundTag":"conflicting-config-options","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}