github/copilot-sdk · error
failed to read tar
Error message
failed to read tar: %w
What it means
extractCLILicense iterates the tar entries with tarReader.Next() to find package/LICENSE.md or package/LICENSE. Any error other than io.EOF while advancing the tar stream (i.e., malformed tar data after a valid gzip header) is wrapped as this error. It signals the decompressed archive is not a coherent tar stream.
Solutions
- Delete the cached tarball and re-download; the checksum flow will validate the new copy.
- Test archive integrity with tar -tzf <tarball> to localize the corruption.
- Ensure nothing writes to the tarball after download (avoid shared cache paths).
- Verify the release asset itself (upstream) is intact if fresh downloads also fail.
Example fix
// before: reusing a cached tarball of unknown integrity
licenseExtracted := extractCLILicense(cachedTarball, outputDir, licensePath)
// after: only trust tarballs whose checksum still matches
if sha256File(cachedTarball) != expectedChecksum {
cachedTarball = reDownloadRelease()
}
extractCLILicense(cachedTarball, outputDir, licensePath) Defensive patterns
Strategy: validation
Validate before calling
// validate archive integrity before license extraction
if err := verifySha256(tarballPath, expectedChecksum); err != nil {
tarballPath = reDownloadRelease(expectedChecksum)
} Try / catch
if err := buildBundle(...); err != nil {
if strings.Contains(err.Error(), "failed to read tar") {
os.Remove(tarballPath); reDownload(); return retryBuild()
}
return err
} Prevention
- Always validate SHA-256 before consuming cached tarballs.
- Treat any non-EOF tar error as corruption; never continue past it.
- Use immutable, per-build cache entries to prevent mid-stream mutation.
- Test upstream release assets if fresh downloads keep failing.
When it happens
Trigger: tarReader.Next() returns a non-EOF error mid-iteration — tar header corruption inside a nominally valid gzip stream, truncated archive, or data appended/corrupted after gzip layer.
Common situations: Partially downloaded tarball that still begins with a valid gzip header; storage bit-rot of a cached tarball; corrupted cache directory reused between builds.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- failed to extract runtime wrapper compatibility entrypoint
- failed to create gzip reader
- failed to extract CLI license
- binary not found after extraction
- failed to open release package
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/2142cb431937ee53.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:1104
if err != nil {
return fmt.Errorf("failed to open release package: %w", err)
}
defer source.Close()
gzReader, err := gzip.NewReader(source)
if err != nil {
return fmt.Errorf("failed to create gzip reader: %w", err)
}
defer gzReader.Close()
tarReader := tar.NewReader(gzReader)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("failed to read tar: %w", err)
}
switch header.Name {
case "package/LICENSE.md", "package/LICENSE":
licenseName := filepath.Base(licensePath)
if err := extractFileFromTarballStream(tarReader, outputDir, licenseName, os.FileMode(header.Mode)); err != nil {
return fmt.Errorf("failed to write license: %w", err)
}
return nil
}
}
return fmt.Errorf("license file not found in tarball")
}
func licensePathForOutput(outputPath string) string {
if strings.HasSuffix(outputPath, ".zst") {
return strings.TrimSuffix(outputPath, ".zst") + ".license"
}View on GitHub (pinned to cd8cf15dc3)