jdx/mise · error · eyre::Report
base image {ref_} has {} layers in its manifest but {} diff_
Error message
base image {ref_} has {} layers in its manifest but {} diff_ids in its config — refusing to emit an OCI-spec-violating image What it means
When `mise oci build` uses a base image (--from), it pulls the base's manifest and config and cross-checks that the number of layers in the manifest equals the number of entries in rootfs.diff_ids in the config — a requirement of the OCI image spec. A mismatch means the base image itself is malformed; mise refuses to emit a derived image whose layer chain would violate the spec, rather than producing an unloadable/unrunnable artifact.
Source
Thrown at src/oci/builder.rs:254
.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 reuse_index = self
.optsView on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Pull the base by immutable digest instead of a mutable tag to avoid concurrent-repush skew
- Rebuild and re-push the base image with a spec-compliant tool (docker buildx) so manifest and config agree
- Try a different tag or a well-known official base image to confirm the base is the problem
- Verify externally: `docker manifest inspect <ref>` and compare layer count with the config's rootfs.diff_ids
Example fix
# before $ mise oci build --from myregistry.internal/base:latest ... # after (pin digest) $ mise oci build --from myregistry.internal/base@sha256:<digest> ...
Defensive patterns
Strategy: fallback
Validate before calling
docker manifest inspect <base-ref> 2>/dev/null | python3 -c "import json,sys; m=json.load(sys.stdin); print('layers:', len(m.get('layers',[])))" # compare against config rootfs.diff_ids count before building Try / catch
Catch this error during `oci build --from`; fall back to a pinned digest or an alternative well-formed base tag, and report the offending ref — do not retry the same malformed base.
Prevention
- Pin base images by digest (@sha256:...) rather than mutable tags
- Produce base images with mainstream builders (docker buildx) that keep manifest and config consistent
- Include a base-image manifest/config sanity check in the pipeline that publishes your base
When it happens
Trigger: Building on a base image pushed by a buggy or non-conformant builder, or a registry/manifest service returning mismatched manifest and config for a tag (sometimes caused by concurrent re-pushes of the same tag, or multi-platform manifest-list skew where the wrong config is fetched for the selected platform).
Common situations: Base images from minimal/exotic build systems (hand-rolled OCI writers); a registry tag being re-pushed mid-pull; platform mismatches when pulling an arch-specific base; cache proxies serving stale configs.
Related errors
- fetching {manifest_url} failed: {}
- manifest push failed: {} {url}{} {}
- push destination must be a fully-qualified reference (e.g. `
- --cache-from must reference the same repository as the desti
- `auth` for {key} is not `user:password`
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/e7fe5d178501c400.
Report an issue: GitHub.