helm/helm · error

invalid version %s for dependency %s: %w

Error message

invalid version %s for dependency %s: %w

What it means

Thrown by Manager.downloadAll when semver.NewVersion cannot parse the version of the locally vendored dependency chart — i.e. the Chart.yaml inside charts/<name>/ has a non-semver version string. Note the message prints dep.Version (the constraint from the parent chart) while the actual parse failure is on ch.Metadata.Version of the vendored chart, which can be confusing.

Source

Thrown at pkg/downloader/manager.go:296

	for _, dep := range deps {
		// No repository means the chart is in charts directory
		if dep.Repository == "" {
			fmt.Fprintf(m.Out, "Dependency %s did not declare a repository. Assuming it exists in the charts directory\n", dep.Name)
			// NOTE: we are only validating the local dependency conforms to the constraints. No copying to tmpPath is necessary.
			chartPath := filepath.Join(destPath, dep.Name)
			ch, err := loader.LoadDir(chartPath)
			if err != nil {
				return fmt.Errorf("unable to load chart '%s': %w", chartPath, err)
			}

			constraint, err := semver.NewConstraint(dep.Version)
			if err != nil {
				return fmt.Errorf("dependency %s has an invalid version/constraint format: %w", dep.Name, err)
			}

			v, err := semver.NewVersion(ch.Metadata.Version)
			if err != nil {
				return fmt.Errorf("invalid version %s for dependency %s: %w", dep.Version, dep.Name, err)
			}

			if !constraint.Check(v) {
				saveError = fmt.Errorf("dependency %s at version %s does not satisfy the constraint %s", dep.Name, ch.Metadata.Version, dep.Version)
				break
			}
			continue
		}
		if strings.HasPrefix(dep.Repository, "file://") {
			if m.Debug {
				fmt.Fprintf(m.Out, "Archiving %s from repo %s\n", dep.Name, dep.Repository)
			}
			ver, err := tarFromLocalDir(m.ChartPath, dep.Name, dep.Repository, dep.Version, tmpPath, m.SourceDateEpoch)
			if err != nil {
				saveError = err
				break
			}
			dep.Version = ver

View on GitHub (pinned to 2a29f1770b)

Solutions

  1. Open charts/<name>/Chart.yaml and check its version field (the parent's dep.Version in the message is a red herring for the parsed value).
  2. Set a valid semantic version, e.g. version: 1.2.3 (pre-release/metadata like 1.2.3-rc.1+build are fine).
  3. Repackage/re-vendor the corrected subchart and re-run helm dependency update.
  4. Add a CI check (helm lint) on vendored subcharts to catch non-semver versions early.

Example fix

# before (charts/common/Chart.yaml)
apiVersion: v2
name: common
version: latest

# after
apiVersion: v2
name: common
version: 2.3.1
Defensive patterns

Strategy: validation

Validate before calling

func vendoredVersionOK(chartPath, name string) error {
	c, err := loader.LoadDir(filepath.Join(chartPath, "charts", name))
	if err != nil { return err }
	if _, err := semver.NewVersion(c.Metadata.Version); err != nil {
		return fmt.Errorf("vendored chart %s has non-semver version %q", name, c.Metadata.Version)
	}
	return nil
}

Prevention

When it happens

Trigger: `helm dependency update/build` with a repository-less dependency where charts/<name>/Chart.yaml contains an invalid version: "latest", "dev", "1.2", empty string, or a commit SHA.

Common situations: Vendored subcharts generated by scripts that stamp git SHAs or branch names into version; placeholder versions like 0.1.0-SNAPSHOT variants that are valid but strings like "VERSION" are not; charts copied from source repos that never set a semver version.

Related errors


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