jdx/mise · critical

base image {ref_} has {base_layers.len} layers in its manife

Error message

base image {ref_} has {base_layers.len} layers in its manifest but {base_diff_ids.len} diff_ids in its config — refusing to emit an OCI-spec-violating image

What it means

When reusing a base image, mise cross-checks the manifest's layer list against the config's `rootfs.diff_ids` array; the OCI spec requires one diff_id per layer. If the counts diverge, the downloaded base image is malformed or mismatched (or the two documents came from different images), and mise refuses to build a spec-violating image on top of it.

Source

Thrown at src/oci/builder.rs:261

                .get("rootfs")
                .and_then(|r| r.get("diff_ids"))
                .and_then(|d| d.as_array())
                .ok_or_else(|| {
                    eyre::eyre!(
                        "pulled base image {ref_} has no rootfs.diff_ids in its config \
                         — cannot produce a valid OCI image on top of it"
                    )
                })?;
            base_diff_ids = diff_ids_raw
                .iter()
                .map(|v| {
                    v.as_str().map(String::from).ok_or_else(|| {
                        eyre::eyre!("base image {ref_} has a non-string entry in rootfs.diff_ids")
                    })
                })
                .collect::<Result<Vec<_>>>()?;
            if base_diff_ids.len() != base_layers.len() {
                bail!(
                    "base image {ref_} has {} layers in its manifest but {} diff_ids in its \
                     config — refusing to emit an OCI-spec-violating image",
                    base_layers.len(),
                    base_diff_ids.len()
                );
            }
            platform = pull.platform;
            base_config_json = Some(pull.config_json);
        }

        // --- 2. Decide layer reuse and validate tool installs ---
        // A tool layer is reused from the remote cache image when tool,
        // version, in-image prefix, and file owner all match — in that case
        // the layer is never built locally and the tool doesn't need to be
        // installed at all.
        let owner_str = format!("{}:{}", owner.uid, owner.gid);
        let python_relocations: Vec<PythonRelocation> = versions
            .iter()

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Re-pull the base image (clear any cache/mirror) so manifest and config come from the same digest-pinned source: `docker pull <ref>@sha256:<digest>` and pin the digest in config.
  2. Verify the registry/mirror isn't rewriting content; bypass the mirror and pull from the upstream registry.
  3. Check for tooling that edited the image config (custom `docker commit`/save-load round trips) and regenerate the base image.
  4. Report the mismatch to the registry operator if a specific tag consistently returns inconsistent manifest/config.

Example fix

// before (mutable tag through a flaky mirror)
let base = "mirror.internal/mybase:latest";
// after (digest-pinned, consistent manifest+config)
let base = "mirror.internal/mybase@sha256:abc123...";
Defensive patterns

Strategy: validation

Validate before calling

// before building, verify layer/diff_id consistency of the base image
const ok = baseManifest.layers.length === baseConfig.rootfs.diff_ids.length;
if (!ok) throw new Error('base image manifest/config layer count mismatch — re-pull');

Prevention

When it happens

Trigger: Pulling a base image whose manifest and config disagree on layer count — e.g. a corrupted/mutated registry cache, a proxy or mirror serving mismatched blobs, or fetching the manifest of one tag and the config of another.

Common situations: Corporate registry mirrors rewriting manifests; interrupted/corrupted local image caches; manually constructing or trimming image layers; registry bugs after force-pushing a tag with different content.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/06458709e0ef78d0. Report an issue: GitHub.