jdx/mise · error · eyre::Report
{}: index.json lists {} manifests; multi-manifest layouts ar
Error message
{}: index.json lists {} manifests; multi-manifest layouts are not supported What it means
Same layout reader as the empty-index case, but here index.json lists more than one manifest. mise only supports pushing single-manifest layouts (one platform); a multi-manifest index — such as a multi-platform bundle from `docker buildx --output type=oci`, ORAS, or hand-merged layouts — is rejected because push cannot decide which manifest represents the image.
Source
Thrown at src/oci/registry.rs:932
update_index: bool,
) -> Result<PushSummary> {
eyre::ensure!(
!crate::config::Settings::get().offline(),
"offline mode is enabled"
);
let r = Reference::parse(reference)?;
let layout = ImageLayout {
root: image_dir.to_path_buf(),
};
// Resolve the layout's single manifest. `mise oci build` always writes
// exactly one manifest into index.json.
let index_bytes = crate::file::read(image_dir.join("index.json"))?;
let index: ImageIndex = serde_json::from_slice(&index_bytes).wrap_err("parsing index.json")?;
let manifest_desc = match index.manifests.as_slice() {
[one] => one,
[] => bail!("{}: index.json lists no manifests", image_dir.display()),
many => bail!(
"{}: index.json lists {} manifests; multi-manifest layouts are not supported",
image_dir.display(),
many.len()
),
};
let manifest_bytes = layout.read_blob(&manifest_desc.digest)?;
let manifest: ImageManifest =
serde_json::from_slice(&manifest_bytes).wrap_err("parsing image manifest blob")?;
// Cross-repo mount source: the base image's repository, when it lives on
// the destination registry (and isn't the destination repo itself).
let mount_from = manifest
.annotations
.get(ANNOTATION_BASE_NAME)
.and_then(|name| Reference::parse(name).ok())
.filter(|base| base.registry == r.registry && base.repository != r.repository)
.map(|base| base.repository);
View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Push the layout produced by `mise oci build` for a single platform — do not point mise at buildx/ORAS multi-platform exports
- Build one platform at a time so each layout keeps exactly one manifest
- Use `crane push`/`oras push` for hand-assembled or multi-manifest layouts; use mise oci push for mise-built layouts
Defensive patterns
Strategy: validation
Validate before calling
// Reject multi-manifest layouts before push (same guard, count > 1).
fn layout_manifest_count(image_dir: &Path) -> usize {
std::fs::read(image_dir.join("index.json"))
.ok()
.and_then(|b| serde_json::from_slice::<serde_json::Value>(&b).ok())
.and_then(|v| v["manifests"].as_array().map(|a| a.len()))
.unwrap_or(0)
}
if layout_manifest_count(&image_dir) != 1 {
anyhow::bail!("push needs a single-manifest mise-built layout");
} Type guard
fn is_single_manifest_layout(image_dir: &Path) -> bool {
layout_manifest_count(image_dir) == 1
} Prevention
- Keep one platform per layout directory; never merge buildx/ORAS outputs into a mise image dir
- Push multi-platform bundles with crane/oras, reserve mise oci push for mise-built layouts
When it happens
Trigger: Pushing a layout directory produced by external multi-platform tooling, or one mutated by appending manifests to index.json, instead of the layout written by `mise oci build`.
Common situations: Teams mixing docker buildx OCI exports with mise oci build outputs in one artifacts dir; hand-assembling multi-arch indexes then trying to push via mise.
Related errors
- {}: index.json lists no manifests
- {}: does not look like an OCI image layout (missing index.js
- fetching {manifest_url} failed: {}
- starting blob upload failed: {} {}{}
- blob chunk upload failed: {}{} {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/cca9a8dbb3efd71b.
Report an issue: GitHub.