helm/helm · error

failed to download plugin: %w

Error message

failed to download plugin: %w

What it means

Returned by HTTPInstaller.GetVerificationData when getter.Get(i.Source) fails during a --verify install: the HTTP(S) download of the plugin tarball itself failed before provenance data could even be fetched. It wraps a pkg/getter error such as DNS resolution failure, a non-2xx status, TLS certificate error, or proxy refusal. Note this is the verification path; the same download on the plain install path returns the bare getter error.

Source

Thrown at internal/plugin/installer/http_installer.go:174

}

// SupportsVerification returns true if the HTTP installer can verify plugins
func (i *HTTPInstaller) SupportsVerification() bool {
	// Only support verification for tarball URLs
	return strings.HasSuffix(i.Source, ".tgz") || strings.HasSuffix(i.Source, ".tar.gz")
}

// GetVerificationData returns cached plugin and provenance data for verification
func (i *HTTPInstaller) GetVerificationData() (archiveData, provData []byte, filename string, err error) {
	if !i.SupportsVerification() {
		return nil, nil, "", errors.New("verification not supported for this source")
	}

	// Download plugin data once and cache it
	if i.pluginData == nil {
		data, err := i.getter.Get(i.Source)
		if err != nil {
			return nil, nil, "", fmt.Errorf("failed to download plugin: %w", err)
		}
		i.pluginData = data.Bytes()
	}

	// Download prov data once and cache it if available
	if i.provData == nil {
		provData, err := i.getter.Get(i.Source + ".prov")
		if err != nil {
			// If provenance file doesn't exist, set provData to nil
			// The verification logic will handle this gracefully
			i.provData = nil
		} else {
			i.provData = provData.Bytes()
		}
	}

	return i.pluginData, i.provData, filepath.Base(i.Source), nil
}

View on GitHub (pinned to 2a29f1770b)

Solutions

  1. Reproduce outside Helm: curl -fIL <url> to see the actual status code and redirect chain
  2. Fix the URL or re-upload the artifact so the .tgz returns 200 directly
  3. Configure proxy/TLS environment (HTTPS_PROXY, SSL_CERT_FILE) if curl also fails
  4. Retry once for transient 5xx/network errors before treating it as a hard failure

Example fix

# before
helm plugin install --verify https://old.example.com/myplugin-1.0.0.tgz
# after: confirm reachability first, then install from the live URL
curl -fsSI https://cdn.example.com/myplugin-1.0.0.tgz && \
helm plugin install --verify https://cdn.example.com/myplugin-1.0.0.tgz
Defensive patterns

Strategy: retry

Validate before calling

func reachable(url string) error {
	resp, err := http.Head(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 400 {
		return fmt.Errorf("%s returned %d", url, resp.StatusCode)
	}
	return nil
}

Try / catch

var err error
for attempt := 1; attempt <= 3; attempt++ {
	_, err = installer.InstallWithOptions(inst, installer.Options{Verify: true})
	if err == nil || !isTransient(err) { // isTransient: unwrap and match net.Error timeouts / 5xx text
		break
	}
	time.Sleep(time.Duration(attempt) * time.Second)
}

Prevention

When it happens

Trigger: helm plugin install --verify https://host/myplugin-1.0.0.tgz where the URL returns 404/403/5xx, DNS fails, the TLS cert is untrusted, or an egress proxy blocks the request. Also triggered when the URL only works in a browser because it silently redirects to an auth page.

Common situations: CI runners without network egress; plugin artifact moved to a new host but docs still point at the old URL; private hosting that requires auth the getter has no credentials for; self-signed certificates on internal artifact servers.

Related errors


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