rancher/rancher · error

unable to find the required chart tar file for %s

Error message

unable to find the required chart tar file for %s

What it means

oci.Chart copied and parsed the manifest successfully but found no Helm content: either the artifactType/config media type is not application/vnd.cncf.helm.config.v1+json, or no layer carries media type application/vnd.cncf.helm.chart.content.v1.tar+gzip. The reference is simply not packaged as a Helm chart.

Source

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

		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
			}
		}
	}

	return nil, fmt.Errorf("unable to find the required chart tar file for %s", chartURL)
}

// GenerateIndex creates a Helm repo index from the OCI url provided
// by fetching the repositories and then the tags according to the url.
// Lastly, adds the chart entry to the Helm repo index using the oras library.
func GenerateIndex(ociClient *Client, URL string, credentialSecret *corev1.Secret,
	clusterRepoSpec v1.RepoSpec,
	clusterRepoStatus v1.RepoStatus,
	indexFile *repo.IndexFile) (*repo.IndexFile, error) {
	logrus.Debugf("Generating index for oci clusterrepo URL %s", URL)

	// Checking if the URL specified by the user is a oras repository or not ?
	IsOrasRepository, err := ociClient.IsOrasRepository()
	if err != nil {
		return nil, err
	}

	var maxTag string

View on GitHub (pinned to 932558d4e6)

Solutions

  1. Push the chart with helm push chart.tgz oci://reg/charts so the Helm media types are set correctly
  2. Verify with crane manifest: the config mediaType must be application/vnd.cncf.helm.config.v1+json and one layer must be the chart content type
  3. Correct the ClusterRepo URL to reference the actual chart repository path

Example fix

# before
oras push reg/foo:1.0 ./chart.tgz:application/octet-stream
# after
helm package ./foo && helm push foo-1.0.0.tgz oci://reg/charts
Defensive patterns

Strategy: type-guard

Validate before calling

// fetch and decode the manifest, then guard before treating it as a chart
blob, err := content.FetchAll(ctx, memoryStore, manifest)
if err != nil {
	return err
}
var m ocispecv1.Manifest
if err := json.Unmarshal(blob, &m); err != nil {
	return err
}
if !isHelmChartManifest(m) {
	return fmt.Errorf("ref is not packaged as a helm chart")
}

Type guard

func isHelmChartManifest(m ocispecv1.Manifest) bool {
	if m.ArtifactType != registry.ConfigMediaType && m.Config.MediaType != registry.ConfigMediaType {
		return false
	}
	for _, l := range m.Layers {
		if l.MediaType == registry.ChartLayerMediaType {
			return true
		}
	}
	return false
}

Prevention

When it happens

Trigger: oci.Chart called on a generic OCI artifact or container image that happens to be a single manifest; chart pushed with custom tooling (oras push with arbitrary layer types) that did not set the Helm config and chart media types.

Common situations: ClusterRepo OCI URL pointing at an app image rather than a chart; manually crafted oras artifacts with a tar layer but a default config blob.

Related errors


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