{"record":{"id":"be7fa2e003452a2a","repo":"helm/helm","slug":"unknown-type-b-in-s-be7fa2","errorCode":null,"errorMessage":"unknown type: %b in %s","messagePattern":"unknown type: %b in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/plugin/installer/oci_installer.go","lineNumber":253,"sourceCode":"\t\tcase tar.TypeReg:\n\t\t\tdir := filepath.Dir(path)\n\t\t\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\toutFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer outFile.Close()\n\t\t\tif _, err := io.Copy(outFile, tarReader); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase tar.TypeXGlobalHeader, tar.TypeXHeader:\n\t\t\t// Skip these\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown type: %b in %s\", header.Typeflag, header.Name)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// SupportsVerification returns true since OCI plugins can be verified\nfunc (i *OCIInstaller) SupportsVerification() bool {\n\treturn true\n}\n\n// GetVerificationData downloads and caches plugin and provenance data from OCI registry for verification\nfunc (i *OCIInstaller) GetVerificationData() (archiveData, provData []byte, filename string, err error) {\n\tslog.Debug(\"getting verification data for OCI plugin\", \"source\", i.Source)\n\n\t// Download plugin data once and cache it\n\tif i.pluginData == nil {\n\t\tpluginDataBuffer, err := i.getter.Get(i.Source)","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/internal/plugin/installer/oci_installer.go#L235-L271","documentation":"Thrown by extractTar in the OCI plugin installer when a tar entry's Typeflag is not one of the supported kinds (TypeDir, TypeReg, TypeXHeader, TypeXGlobalHeader). Helm's extractor only writes directories and regular files; any other entry type — symlinks (2), hardlinks (1), FIFOs (6), char/block devices (3/4) — aborts installation. Note the format verb is %b, so the byte prints in binary (e.g. symlinks show as 1000010).","triggerScenarios":"Installing an OCI plugin whose tar layer contains symlinks (most common: plugin ships a bin symlink or was built from a node/python tree with linked dependencies), hardlinked files, FIFOs or device nodes; archives produced by tools that store hardlinks for duplicate files (e.g. some deterministic build tooling).","commonSituations":"Plugin authors using 'ln -s' in their build script; wasm/native binaries shared across directories via hardlinks; packaging on macOS where some tools emit symlinks for .dylibs; copying node_modules into the distribution tarball.","solutions":["Rebuild the plugin tarball without symlinks/hardlinks: replace symlinks with copies (cp -L) and repackage with tar (GNU tar stores hardlinks as TypeLink for duplicate files — deduplicate or use --hard-dereference).","Check for offending entries: tar -tvzf plugin.tgz | grep -E '^[hl]' lists links; anything shown must be materialized as a real file.","If the link is essential (e.g. platform-specific binary dispatch), restructure the plugin to use a wrapper script or platformDirs in plugin.yaml instead.","Push the fixed artifact and reinstall: helm plugin remove <name> && helm plugin install oci://..."],"exampleFix":"# before: build step creates a symlink\nln -s bin/helm-plugin-linux-amd64 bin/helm-plugin\n# after: ship a real file (or wrapper script)\ncp bin/helm-plugin-linux-amd64 bin/helm-plugin\nchmod +x bin/helm-plugin","handlingStrategy":"validation","validationCode":"func tarHasOnlySupportedTypes(r io.Reader) (bool, error) {\n    tr := tar.NewReader(r)\n    for {\n        h, err := tr.Next()\n        if errors.Is(err, io.EOF) { return true, nil }\n        if err != nil { return false, err }\n        switch h.Typeflag {\n        case tar.TypeDir, tar.TypeReg, tar.TypeXHeader, tar.TypeXGlobalHeader:\n        default:\n            return false, nil\n        }\n    }\n}","typeGuard":"func isSupportedTarType(flag byte) bool {\n    return flag == tar.TypeDir || flag == tar.TypeReg || flag == tar.TypeXHeader || flag == tar.TypeXGlobalHeader\n}","tryCatchPattern":"if err := installer.Install(); err != nil {\n    if strings.Contains(err.Error(), \"unknown type:\") {\n        // repack artifact: materialize links as real files (--dereference, cp -L)\n    }\n}","preventionTips":["Run tar -tvzf plugin.tgz | grep -Ev '^(d|-)' in CI to fail on links/devices before publish.","Avoid ln -s in plugin build scripts; copy binaries instead.","Use --hard-dereference when GNU tar may store duplicate files as hardlinks."],"tags":["plugins","oci","tar","symlinks","packaging"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}