helm/helm · error
failed to create plugin tarball: %w
Error message
failed to create plugin tarball: %w
What it means
The output file was created successfully, but plugin.CreatePluginTarball (internal/plugin/sign.go:105) failed while walking the plugin source directory and copying files into the tar writer. The half-written archive is cleaned up with os.Remove before the error is returned. Causes are per-file problems inside the plugin directory: unreadable files, permission bits, broken symlinks.
Source
Thrown at pkg/cmd/plugin_package.go:139
// User explicitly disabled signing
fmt.Fprint(out, "WARNING: Skipping plugin signing. This is not recommended for plugins intended for distribution.\n")
}
// Now create the tarball (only after signing prerequisites are met)
// Use plugin metadata for filename: PLUGIN_NAME-SEMVER.tgz
metadata := pluginMeta.Metadata()
filename := fmt.Sprintf("%s-%s.tgz", metadata.Name, metadata.Version)
tarballPath := filepath.Join(o.destination, filename)
tarFile, err := os.Create(tarballPath)
if err != nil {
return fmt.Errorf("failed to create tarball: %w", err)
}
defer tarFile.Close()
if err := plugin.CreatePluginTarball(o.pluginPath, metadata.Name, tarFile); err != nil {
os.Remove(tarballPath)
return fmt.Errorf("failed to create plugin tarball: %w", err)
}
tarFile.Close() // Ensure file is closed before signing
// If signing was requested, sign the tarball
if o.sign {
// Read the tarball data
tarballData, err := os.ReadFile(tarballPath)
if err != nil {
os.Remove(tarballPath)
return fmt.Errorf("failed to read tarball for signing: %w", err)
}
// Sign the plugin tarball data
sig, err := plugin.SignPlugin(tarballData, filepath.Base(tarballPath), signer)
if err != nil {
os.Remove(tarballPath)
return fmt.Errorf("failed to sign plugin: %w", err)
}View on GitHub (pinned to 2a29f1770b)
Solutions
- Check the wrapped error to identify which file failed to read
- Fix readability: `chmod -R u+rX ./my-plugin` and repair/remove broken symlinks
- Re-run once concurrent writes to the plugin directory have stopped
Example fix
# before helm plugin package ./my-plugin --destination ./dist # error: failed to create plugin tarball: open ./my-plugin/bin/helm-my-plugin: permission denied # after chmod -R u+rX ./my-plugin && helm plugin package ./my-plugin --destination ./dist
Defensive patterns
Strategy: try-catch
Validate before calling
func checkPluginFilesReadable(root string) error {
return filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.Mode().IsRegular() && info.Mode().Perm()&0o400 == 0 {
return fmt.Errorf("file not readable: %s", p)
}
if info.Mode()&os.ModeSymlink != 0 {
if _, err := os.Stat(p); err != nil {
return fmt.Errorf("broken symlink: %s", p)
}
}
return nil
})
} Try / catch
if err := runPluginPackage(args); err != nil {
if strings.Contains(err.Error(), "failed to create plugin tarball") {
// tarball was cleaned up by helm; fix file perms and retry once
_ = exec.Command("chmod", "-R", "u+rX", pluginDir).Run()
return runPluginPackage(args)
}
return err
} Prevention
- Check file permissions and broken symlinks in the plugin dir before packaging
- Avoid concurrent writes to the plugin directory during release builds
When it happens
Trigger: A file inside the plugin dir with mode 000 or owned by another user; a symlink pointing to a nonexistent target; a file deleted concurrently while the tar walk is in progress.
Common situations: Restrictive umask or ownership after copying plugin files in CI; committed broken symlinks (e.g. node_modules style link farms); antivirus quarantining a binary mid-read on Windows.
Related errors
- unknown type: %b in %s
- failed to create tarball: %w
- only unpacked charts can be updated
- is not a directory: %s
- failed to create cache directory: %w
AI-assisted analysis of helm/helm@2a29f1770b (2026-08-15).
Data as JSON: /api/errors/8edb28898351981d.
Report an issue: GitHub.