{"record":{"id":"b25fcf332ec38806","repo":"jdx/mise","slug":"podman-pull-failed-stderr","errorCode":null,"errorMessage":"podman pull failed: {}: {stderr}","messagePattern":"podman pull failed: (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/oci/run.rs","lineNumber":275,"sourceCode":"/// Load the OCI layout at `image_dir` into the given engine and return the\n/// image reference that should be passed to the engine's `run` subcommand.\n///\n/// We don't rely on `podman tag` here because `podman tag` takes an image\n/// name/ID (not a transport reference), and the image name that `podman\n/// pull oci:<dir>` assigns depends on the layout's `ref.name` annotation\n/// and the podman version. Capturing the image ID printed by\n/// `podman pull --quiet` is deterministic across versions.\nfn load_image(engine: Engine, image_dir: &Path) -> Result<String> {\n    match engine {\n        Engine::Podman => {\n            let src = format!(\"oci:{}\", image_dir.display());\n            let out = Command::new(\"podman\")\n                .args([\"pull\", \"--quiet\", &src])\n                .output()\n                .wrap_err(\"running `podman pull`\")?;\n            if !out.status.success() {\n                let stderr = String::from_utf8_lossy(&out.stderr);\n                bail!(\"podman pull failed: {}: {stderr}\", out.status);\n            }\n            // `podman pull --quiet` prints just the image ID on stdout.\n            let id = String::from_utf8(out.stdout)\n                .wrap_err(\"podman pull produced non-utf8 output\")?\n                .trim()\n                .to_string();\n            if id.is_empty() {\n                bail!(\"podman pull succeeded but printed no image ID\");\n            }\n            Ok(id)\n        }\n        Engine::Docker => {\n            // Stream the layout into `docker load` as a docker-archive. Pick\n            // a per-invocation tag so concurrent `mise oci run` calls don't\n            // clobber each other — a shared `mise-oci:run` tag would\n            // otherwise race: the second load would overwrite the first\n            // image before the first container started.\n            let tag = format!(","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/cli/oci/run.rs#L257-L293","documentation":"To run an image, mise loads the built OCI layout into podman via `podman pull --quiet oci:<image_dir>` and treats a non-zero exit as failure, embedding the engine's exit status and full stderr in the error. The root cause is always in podman's output: corrupted/partial layout, unsupported layout features, storage/permission problems.","triggerScenarios":"A previous build was interrupted leaving truncated blobs in --image-dir; podman's storage is full or its DB is corrupted; a very old podman that cannot read the layout's manifest; the layout directory is not readable by the current user.","commonSituations":"Reusing a stale --image-dir across mise versions; rootless podman with a full ~/.local/share/containers; CI caching half-written layout directories; SELinux denying access to the layout path.","solutions":["Read the embedded stderr — it names the actual podman failure","Drop --image-dir to force a fresh build into a clean temp dir and retry","Reclaim/repair engine storage: `podman system prune` (or `podman system reset` as last resort)","Upgrade podman if the stderr mentions unsupported manifest/media types; or fall back to `--engine docker`"],"exampleFix":"# before\nmise oci run --image-dir ./stale-layout -- bash\n# after\nmise oci run -- bash   # rebuilds layout fresh, avoiding corrupted blobs","handlingStrategy":"try-catch","validationCode":"# optional pre-flight: if skopeo is available, validate the layout parses\nskopeo inspect \"oci:$IMAGE_DIR\" >/dev/null 2>&1 || { echo \"layout unreadable\" >&2; exit 2; }","typeGuard":null,"tryCatchPattern":"# bash: on pull failure, rebuild the layout once and retry\nif ! mise oci run --image-dir \"$dir\" -- bash; then\n  echo \"pull failed; rebuilding layout\" >&2\n  mise oci build -o \"$dir\" || exit 1\n  mise oci run --image-dir \"$dir\" -- bash || exit 1\nfi","preventionTips":["Don't cache --image-dir directories across jobs/versions without verifying them","Keep podman storage pruned (`podman system prune`) in long-lived dev machines"],"tags":["oci","run","podman","image-pull","container-storage"],"backgroundTag":"image-pull-failure","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}