GoogleContainerTools/skaffold · error · PluginErr

Failed to install Helm plugin

Error message

Failed to install Helm plugin

What it means

PreparePostRenderer installs a helm plugin (postrenderer) via 'helm plugin install' into a temp plugin dir. If that Exec fails, the plugin dir is removed and a PluginErr wrapping 'Failed to install Helm plugin' plus the trimmed helm output is returned. It indicates the helm plugin installation step failed, with helm's own stderr/stdout as the cause detail.

Source

Thrown at pkg/skaffold/helm/bin.go:137

		helmPluginDir = PluginInstallDir
	}

	// Take the temporary directory name as unique plugin name. That string is expected to
	// be safe for direct %s insertion in the YAML Helm plugin manifest.
	helmPluginName := path.Base(helmPluginDir)
	err = os.WriteFile(path.Join(helmPluginDir, "plugin.yaml"), []byte(fmt.Sprintf(PostRendererTemplate, helmPluginName, skaffoldBinaryAsYaml)), 0644)
	if err != nil &&
		// Don't produce an error in tests that simulate the directory
		!strings.HasPrefix(PluginInstallDir, "TEMPORARY-TEST-DIR") {
		os.RemoveAll(helmPluginDir)
		return nil, nil, PluginErr("Failed to write Helm plugin.yaml", err)
	}

	out := new(bytes.Buffer)
	err = Exec(ctx, h, out, false, nil, "plugin", "install", helmPluginDir)
	if err != nil {
		os.RemoveAll(helmPluginDir)
		return nil, nil, PluginErr("Failed to install Helm plugin", errors.New(strings.TrimSpace(out.String())))
	}

	cleanUp := func() {
		Exec(ctx, h, out, false, nil, "plugin", "uninstall", helmPluginName)
		os.RemoveAll(helmPluginDir)
	}
	return cleanUp, []string{"--post-renderer", helmPluginName}, nil
}

func PrepareSkaffoldFilter(h Client, builds []graph.Artifact, flags []string) (skaffoldBinary string, env []string, cleanup func(), err error) {
	skaffoldBinary, err = OSExecutable()
	if err != nil {
		return "", nil, nil, fmt.Errorf("cannot locate this Skaffold binary: %w", err)
	}

	var buildsFile string
	if len(builds) > 0 {
		buildsFile, cleanup, err = WriteBuildArtifacts(builds)

View on GitHub (pinned to a1189de023)

Solutions

  1. Read the wrapped helm output in the error to see helm's own failure reason
  2. Upgrade helm CLI to a version compatible with the plugin's apiVersion
  3. Re-run after clearing any stale plugin state: helm plugin uninstall <name> and remove the plugin directory
  4. Check network/proxy access if the plugin needs to download dependencies

Example fix

// before
helm version  # v3.7 with plugin apiVersion v1 mismatch
// after
# upgrade helm
brew upgrade helm  # or download helm >= required version
helm version
skaffold deploy  # plugin install now succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

v := exec.Command("helm", "version", "--short").Run()
if v != nil {
    return errors.New("helm CLI not usable; plugin install would fail")
}
if _, err := os.Stat(filepath.Join(helmPluginDir, "plugin.yaml")); err != nil {
    return errors.New("helm plugin dir incomplete")
}

Try / catch

_, _, err := h.PreparePostRenderer(ctx, out)
if err != nil && strings.Contains(err.Error(), "Failed to install Helm plugin") {
    log.Printf("helm plugin install failed: %s", err)
    // upgrade helm, clean plugin dirs, then retry once
    exec.Command("helm", "plugin", "uninstall", "postrenderer").Run()
    err = retryPrepare()
}

Prevention

When it happens

Trigger: Calling PreparePostRenderer (directly or via deployRelease/generateHelmManifests) when 'helm plugin install <dir>' fails — e.g. plugin dir missing files, incompatible plugin apiVersion, network failure fetching plugin deps, or helm CLI too old.

Common situations: Helm version mismatch (plugin apiVersion newer than installed helm); offline/air-gapped environment where plugin dependencies cannot be downloaded; leftover corrupted helmPluginDir from a previous failed attempt; restricted filesystem permissions.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/1b561de61a95b993. Report an issue: GitHub.