jdx/mise · error
podman pull failed: {}: {stderr}
Error message
podman pull failed: {}: {stderr} What it means
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.
Source
Thrown at src/cli/oci/run.rs:275
/// Load the OCI layout at `image_dir` into the given engine and return the
/// image reference that should be passed to the engine's `run` subcommand.
///
/// We don't rely on `podman tag` here because `podman tag` takes an image
/// name/ID (not a transport reference), and the image name that `podman
/// pull oci:<dir>` assigns depends on the layout's `ref.name` annotation
/// and the podman version. Capturing the image ID printed by
/// `podman pull --quiet` is deterministic across versions.
fn load_image(engine: Engine, image_dir: &Path) -> Result<String> {
match engine {
Engine::Podman => {
let src = format!("oci:{}", image_dir.display());
let out = Command::new("podman")
.args(["pull", "--quiet", &src])
.output()
.wrap_err("running `podman pull`")?;
if !out.status.success() {
let stderr = String::from_utf8_lossy(&out.stderr);
bail!("podman pull failed: {}: {stderr}", out.status);
}
// `podman pull --quiet` prints just the image ID on stdout.
let id = String::from_utf8(out.stdout)
.wrap_err("podman pull produced non-utf8 output")?
.trim()
.to_string();
if id.is_empty() {
bail!("podman pull succeeded but printed no image ID");
}
Ok(id)
}
Engine::Docker => {
// Stream the layout into `docker load` as a docker-archive. Pick
// a per-invocation tag so concurrent `mise oci run` calls don't
// clobber each other — a shared `mise-oci:run` tag would
// otherwise race: the second load would overwrite the first
// image before the first container started.
let tag = format!(View on GitHub (pinned to 9dcfcaa0dc)
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`
Example fix
# before mise oci run --image-dir ./stale-layout -- bash # after mise oci run -- bash # rebuilds layout fresh, avoiding corrupted blobs
Defensive patterns
Strategy: try-catch
Validate before calling
# optional pre-flight: if skopeo is available, validate the layout parses
skopeo inspect "oci:$IMAGE_DIR" >/dev/null 2>&1 || { echo "layout unreadable" >&2; exit 2; } Try / catch
# bash: on pull failure, rebuild the layout once and retry if ! mise oci run --image-dir "$dir" -- bash; then echo "pull failed; rebuilding layout" >&2 mise oci build -o "$dir" || exit 1 mise oci run --image-dir "$dir" -- bash || exit 1 fi
Prevention
- Don't cache --image-dir directories across jobs/versions without verifying them
- Keep podman storage pruned (`podman system prune`) in long-lived dev machines
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- --engine podman requested but `podman` was not found on PATH
- no supported container engine found. Install podman or docke
- podman pull succeeded but printed no image ID
- {}: does not look like an OCI image layout (missing index.js
- {engine_bin} exited abnormally: {status:?}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/b25fcf332ec38806.
Report an issue: GitHub.