jeessy2/ddns-go · error

tar.gz 文件:

Error message

%w tar.gz 文件:%s

What it means

untar reads successive entries from the tar stream; if t.Next returns a non-EOF error (corrupt tar headers, truncated data, checksum mismatch), it returns errCannotDecompressFile wrapped with this message. The gzip layer succeeded but the inner tar structure is unreadable.

Solutions

  1. Re-download the .tar.gz and verify its checksum against the published checksum file
  2. Confirm the asset is a tar archive (tar -tzf file.tar.gz locally)
  3. Check disk space and integrity of the storage path; use errors.Is(err, errCannotDecompressFile) to confirm
Defensive patterns

Strategy: retry

Validate before calling

// Verify checksum of the downloaded archive before extraction
sum := sha256.Sum256(buf)
if !checksumMatches(hex.EncodeToString(sum[:])) {
    return fmt.Errorf("archive checksum mismatch")
}

Try / catch

r, err := untar(src, cmd)
if err != nil {
    if errors.Is(err, errCannotDecompressFile) {
        // corrupt tar payload: re-download and retry once
        return retryDownload(archiveURL, cmd)
    }
    return err
}

Prevention

When it happens

Trigger: Self-update processes a .tar.gz whose gzip stream decompresses but whose tar payload is corrupt — truncated download, bit-flip in transit, or a file that is gzip but not tar.

Common situations: Interrupted downloads saved as complete; flaky network/proxy corrupting large tarballs; mislabeled assets that are gzip-only or in a different archive format.

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/026f0c3a79d96802. Report an issue: GitHub.

Appendix: source

Thrown at util/update/decompress.go:77

	}

	return nil, fmt.Errorf("在 zip 文件中%w:%q", errExecutableNotFoundInArchive, cmd)
}

func untar(src io.Reader, cmd string) (io.Reader, error) {
	gz, err := gzip.NewReader(src)
	if err != nil {
		return nil, fmt.Errorf("%w tar.gz 文件: %s", errCannotDecompressFile, err)
	}

	t := tar.NewReader(gz)
	for {
		h, err := t.Next()
		if errors.Is(err, io.EOF) {
			break
		}
		if err != nil {
			return nil, fmt.Errorf("%w tar.gz 文件:%s", errCannotDecompressFile, err)
		}
		_, name := filepath.Split(h.Name)
		if matchExecutableName(cmd, name) {
			return t, nil
		}
	}
	return nil, fmt.Errorf("在 tar.gz 文件中%w:%q", errExecutableNotFoundInArchive, cmd)
}

func matchExecutableName(cmd, target string) bool {
	return cmd == target || cmd+".exe" == target
}

View on GitHub (pinned to 5874c2e666)