rancher/rancher · error

unable to fetch the manifest blob of %s: %w

Error message

unable to fetch the manifest blob of %s: %w

What it means

oci.Chart() copies the artifact with oras.Copy into a memory store and then reads the manifest back with content.FetchAll. This error means the manifest descriptor was never stored: PreCopy only accepts MediaTypeImageManifest and the Helm chart layer media type and returns oras.SkipNode for everything else, so a non-conforming root manifest (e.g. an image index) is never fetched and the later FetchAll cannot find it.

Source

Thrown at pkg/catalogv2/oci/oci.go:81

					// and so we are defining a limit before fetching.
					if desc.Size > maxHelmChartTarSize {
						return fmt.Errorf("the oci artifact %s has size more than %d which is not supported", chartURL, maxHelmChartTarSize)
					}
					return nil
				}

				return oras.SkipNode
			},
		},
	})

	if err != nil {
		return nil, fmt.Errorf("unable to oras copy the remote OCI artifact %s: %w", chartURL, err)
	}
	// Fetch the manifest blob of the oci artifact
	manifestBlob, err := content.FetchAll(ctx, memoryStore, manifest)
	if err != nil {
		return nil, fmt.Errorf("unable to fetch the manifest blob of %s: %w", chartURL, err)
	}
	var manifestJSON ocispecv1.Manifest
	err = json.Unmarshal(manifestBlob, &manifestJSON)
	if err != nil {
		return nil, fmt.Errorf("unable to unmarshal manifest blob of %s: %w", chartURL, err)
	}

	// Check if the oci artifact is of type helm config ?
	if manifest.ArtifactType == registry.ConfigMediaType || manifestJSON.Config.MediaType == registry.ConfigMediaType {
		// Find the layer of chart type and fetch it
		for _, layer := range manifestJSON.Layers {
			if layer.MediaType == registry.ChartLayerMediaType {
				chartTar, err := content.FetchAll(ctx, memoryStore, layer)
				if err != nil {
					return nil, err
				}

				return io.NopCloser(bytes.NewBuffer(chartTar)), nil

View on GitHub (pinned to 932558d4e6)

Solutions

  1. Confirm the artifact is a Helm chart pushed with helm push
  2. Inspect the root manifest (crane manifest registry/repo:tag); it must be application/vnd.oci.image.manifest.v1+json, not an index
  3. Re-push the chart using Helm so config and layer media types are the cncf.helm ones

Example fix

# before
spec:
  url: oci://reg/app:1.0   # container image, not a chart
# after
helm package ./app && helm push app-1.0.0.tgz oci://reg/charts
# and point the URL at oci://reg/charts/app:1.0.0
Defensive patterns

Strategy: validation

Validate before calling

// check the root descriptor media type before copying
repo, err := remote.NewRepository("reg/charts/app")
if err != nil {
	return err
}
desc, err := repo.Resolve(ctx, "1.0.0")
if err != nil {
	return err
}
if desc.MediaType != ocispecv1.MediaTypeImageManifest {
	return fmt.Errorf("ref is not a single OCI manifest (got %s); not a helm chart", desc.MediaType)
}

Prevention

When it happens

Trigger: Pointing oci.Chart at a multi-arch image index / manifest list or a generic OCI artifact whose root manifest media type is not application/vnd.oci.image.manifest.v1+json; the copy 'succeeds' while skipping the root node, then the manifest blob lookup fails.

Common situations: ClusterRepo URL referencing a container image or an oras artifact instead of a Helm chart; charts wrapped in an index by custom CI tooling.

Related errors


AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16). Data as JSON: /api/errors/0c8da26333b5fafd. Report an issue: GitHub.