helm/helm · error

cannot load Chart.yaml: %w

Error message

cannot load Chart.yaml: %w

What it means

Thrown by LoadFiles (internal/chart/v3/loader/load.go) when yaml.Unmarshal of the Chart.yaml bytes into chart.Metadata fails. It means the file was found and read, but its content is not parseable as the v3 metadata schema: bad YAML syntax or wrong field types (sigs.k8s.io/yaml round-trips through JSON, so strict typing applies). The chart is returned partially populated (c.Raw already set) alongside the error.

Source

Thrown at internal/chart/v3/loader/load.go:86

	return l.Load()
}

// LoadFiles loads from in-memory files.
func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
	c := new(chart.Chart)
	subcharts := make(map[string][]*archive.BufferedFile)
	var subChartsKeys []string

	// do not rely on assumed ordering of files in the chart and crash
	// if Chart.yaml was not coming early enough to initialize metadata
	for _, f := range files {
		c.Raw = append(c.Raw, &common.File{Name: f.Name, ModTime: f.ModTime, Data: f.Data})
		if f.Name == "Chart.yaml" {
			if c.Metadata == nil {
				c.Metadata = new(chart.Metadata)
			}
			if err := yaml.Unmarshal(f.Data, c.Metadata); err != nil {
				return c, fmt.Errorf("cannot load Chart.yaml: %w", err)
			}
			// While the documentation says the APIVersion is required, in practice there
			// are cases where that's not enforced. Since this package set is for v3 charts,
			// when this function is used v3 is automatically added when not present.
			if c.Metadata.APIVersion == "" {
				c.Metadata.APIVersion = chart.APIVersionV3
			}
			c.ModTime = f.ModTime
		}
	}
	for _, f := range files {
		switch {
		case f.Name == "Chart.yaml":
			// already processed
			continue
		case f.Name == "Chart.lock":
			c.Lock = new(chart.Lock)
			if err := yaml.Unmarshal(f.Data, &c.Lock); err != nil {

View on GitHub (pinned to 2a29f1770b)

Solutions

  1. Validate the syntax directly: helm lint <chart> or yamllint Chart.yaml; also helm show chart <chart> exercises the same parse.
  2. Fix the reported construct: quote version-like strings (version: "1.0"), remove tabs (use spaces), resolve merge-conflict markers, deduplicate keys.
  3. If the file was machine-generated, fix the generator template rather than the output so the error does not recur.
  4. Compare against a known-good scaffold (helm create tmp && cat tmp/Chart.yaml) to spot structural mistakes.

Example fix

# before (Chart.yaml)
apiVersion: v2
name: mychart
version: 1.0        # parses as float, schema wants string
maintainers:
  - name: alice

# after
apiVersion: v2
name: mychart
version: "1.0"
maintainers:
  - name: alice
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate Chart.yaml the same way the loader does.
func chartYamlOK(dir string) error {
    b, err := os.ReadFile(filepath.Join(dir, "Chart.yaml"))
    if err != nil {
        return err
    }
    md := new(chart.Metadata)
    return yaml.Unmarshal(b, md)
}

Prevention

When it happens

Trigger: Any load path that funnels into LoadFiles — loader.LoadDir, loader.LoadArchive, loader.LoadFile on a .tgz — where Chart.yaml has a YAML syntax error, a duplicated key, or a type mismatch such as 'version:' or 'appVersion:' given as a map/list/bool instead of a string (e.g. version: 1.0 without quotes parses as a float, which sigs.k8s.io/yaml rejects for the string field... in practice unquoted multi-part versions and nested values under known scalar fields are the usual culprits).

Common situations: Hand-edited Chart.yaml with tabs, missing colons, or unquoted values that YAML misinterprets (on/off/yes/no as booleans, dates as timestamps); charts generated by scripts that emit broken YAML; merge conflicts left in Chart.yaml.

Related errors


AI-assisted analysis of helm/helm@2a29f1770b (2026-08-15). Data as JSON: /api/errors/bb470a2cb59fec2a. Report an issue: GitHub.