Skip to content

mutate image wrappers assume Docker container image semantics, breaking non-Docker OCI artifacts #2251

@EronWright

Description

@EronWright

The image struct in mutate/image.go is the backing implementation for all v1.Image mutators (Annotations, MediaType, AppendLayers, etc.). Its compute() method unconditionally calls base.ConfigFile() and derives the layer set from configFile.RootFS.DiffIDs. For non-Docker OCI artifacts — Helm charts, WASM modules, arbitrary blobs — the config is not a Docker image config, so RootFS.DiffIDs is empty.

This causes two problems:

  1. Layers() returns an empty slice. remote.Write uses Layers() to determine which blobs to upload. On a cross-repository push, layer blobs are never uploaded, and the registry rejects the manifest with MANIFEST_BLOB_UNKNOWN.

  2. The config blob digest is corrupted. compute() re-marshals the config file and writes the new digest into the manifest, so the manifest now references a config blob whose content differs from the original. The original config blob is never uploaded.

Any mutator that wraps a non-Docker OCI image in the image struct will silently produce an artifact that cannot be pushed cross-repository.

Version: v0.20.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions