helm/helm · error

plugin verification failed: no provenance file (.prov) found

Error message

plugin verification failed: no provenance file (.prov) found

What it means

During verified install (internal/plugin/installer/installer.go:101), after GetVerificationData() succeeds, empty provenance data yields this error before any cryptographic check runs. The .prov file is looked up as Source+".prov" (HTTP/OCI) or read from <tarball>.tgz.prov next to a local tarball; no provenance means nothing to verify the archive against.

Source

Thrown at internal/plugin/installer/installer.go:101

	var result *VerificationResult

	// If verification is requested, check if installer supports it
	if opts.Verify {
		verifier, ok := i.(Verifier)
		if !ok || !verifier.SupportsVerification() {
			return nil, errors.New("--verify is only supported for plugin tarballs (.tgz files)")
		}

		// Get verification data (works for both memory and file-based installers)
		archiveData, provData, filename, err := verifier.GetVerificationData()
		if err != nil {
			return nil, fmt.Errorf("failed to get verification data: %w", err)
		}

		// Check if provenance data exists
		if len(provData) == 0 {
			return nil, errors.New("plugin verification failed: no provenance file (.prov) found")
		}

		// Provenance data exists - verify the plugin
		verification, err := plugin.VerifyPlugin(archiveData, provData, filename, opts.Keyring)
		if err != nil {
			return nil, fmt.Errorf("plugin verification failed: %w", err)
		}

		// Collect verification info
		result = &VerificationResult{
			SignedBy:    make([]string, 0),
			Fingerprint: fmt.Sprintf("%X", verification.SignedBy.PrimaryKey.Fingerprint),
			FileHash:    verification.FileHash,
		}
		for name := range verification.SignedBy.Identities {
			result.SignedBy = append(result.SignedBy, name)
		}
	}

View on GitHub (pinned to 2a29f1770b)

Solutions

  1. Obtain the .prov file from the plugin author and place it next to the tarball (local) or publish it at URL+'.prov' / as an OCI companion
  2. Generate provenance for your own plugin with 'helm plugin sign' style signing tooling before publishing
  3. If trust is established otherwise (checksum from a trusted channel), install without --verify

Example fix

# before
helm plugin install --verify ./myplugin-1.0.0.tgz   # no .prov present

# after
cp ~/downloads/myplugin-1.0.0.tgz.prov .
helm plugin install --verify ./myplugin-1.0.0.tgz --keyring pubring.gpg
Defensive patterns

Strategy: validation

Validate before calling

// local tarball: check the .prov companion before requesting verification
if _, err := os.Stat(tarballPath + ".prov"); errors.Is(err, fs.ErrNotExist) {
	return errors.New("no .prov file next to tarball; --verify would fail")
}
// remote: HEAD/GET the source+".prov" URL and require HTTP 200 before --verify

Try / catch

if _, err := installer.InstallWithOptions(i, opts); err != nil {
	if strings.Contains(err.Error(), "no provenance file (.prov) found") {
		// fetch/publish the .prov, or install without --verify once trust is established
	}
}

Prevention

When it happens

Trigger: 'helm plugin install --verify ./x.tgz' with no x.tgz.prov beside it; an HTTP URL where fetching source+'.prov' 404s (GetVerificationData silently returns nil provData); an OCI ref without a .prov companion artifact.

Common situations: Plugin authors who never generated/published provenance; download mirrors that only host the tarball; wrong keyring/prov file naming (the .prov must be named exactly like the tarball plus '.prov').

Related errors


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