{"record":{"id":"6fca3baada0732b0","repo":"anomalyco/sst","slug":"failed-to-read-tar-entry-w","errorCode":null,"errorMessage":"failed to read tar entry: %w","messagePattern":"failed to read tar entry: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runtime/python/build.go","lineNumber":418,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open archive: %w\", err)\n\t}\n\tdefer f.Close()\n\n\tgz, err := gzip.NewReader(f)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create gzip reader: %w\", err)\n\t}\n\tdefer gz.Close()\n\n\ttr := tar.NewReader(gz)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read tar entry: %w\", err)\n\t\t}\n\n\t\ttarget := filepath.Join(destDir, hdr.Name)\n\t\t// Guard against tar slip\n\t\tif !strings.HasPrefix(filepath.Clean(target), filepath.Clean(destDir)+string(os.PathSeparator)) {\n\t\t\treturn fmt.Errorf(\"illegal file path in tar: %s\", hdr.Name)\n\t\t}\n\n\t\tswitch hdr.Typeflag {\n\t\tcase tar.TypeDir:\n\t\t\tif err := os.MkdirAll(target, 0755); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase tar.TypeReg:\n\t\t\tif err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tout, err := os.OpenFile(target, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(hdr.Mode))","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/runtime/python/build.go#L400-L436","documentation":"While iterating entries with tar.NewReader's tr.Next(), any error other than io.EOF is wrapped as \"failed to read tar entry\". This means the tar stream itself is malformed or the read failed midway — the gzip header was valid but the body is corrupt, truncated, or uses unsupported tar features.","triggerScenarios":"tr.Next() hits the end of a truncated gzip stream (unexpected EOF), the tar headers are malformed (header check-sum mismatch), or an underlying file read error occurs while streaming the archive.","commonSituations":"A download was interrupted at, say, 90% and cached; a mirror serves a cut-off archive; disk I/O failure while streaming; an archive produced by a non-standard tool with unusual header formats.","solutions":["Re-download the archive and verify its checksum against the index-provided hash","Test the archive manually (tar -tzf archive.tar.gz) to confirm it is intact","Remove any cached/partial artifact before rebuilding","Use a different mirror or the official PyPI index","If archives are custom-built, verify the packing tool produces standard ustar/pax tar output"],"exampleFix":"// before\nextractTarGz(archiveFile, destDir)\n\n// after: validate archive integrity first\ncmd := exec.Command(\"tar\", \"-tzf\", archiveFile)\nif err := cmd.Run(); err != nil {\n    os.Remove(archiveFile)\n    return fmt.Errorf(\"archive %s is corrupt, re-downloading\", archiveFile)\n}\nextractTarGz(archiveFile, destDir)","handlingStrategy":"validation","validationCode":"cmd := exec.Command(\"tar\", \"-tzf\", archiveFile)\ncmd.Stdout = io.Discard\nif err := cmd.Run(); err != nil {\n    return fmt.Errorf(\"archive %s failed integrity check: %w\", archiveFile, err)\n}","typeGuard":null,"tryCatchPattern":"if err := extractTarGz(archiveFile, destDir); err != nil {\n    if strings.Contains(err.Error(), \"failed to read tar entry\") {\n        os.Remove(archiveFile) // truncated/corrupt tar: refetch\n        return retryDownloadAndExtract()\n    }\n    return err\n}","preventionTips":["Compare the archive checksum with the hash published by the package index","Run tar -tzf as a smoke test before extraction","Never cache partially downloaded files","Prefer wheels over sdists when integrity issues recur"],"tags":["tar","archive","corrupt-file","python"],"backgroundTag":"corrupt-archive","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}