multica-ai/multica · error

read checksum manifest: %w

Error message

read checksum manifest: %w

What it means

parseChecksumManifest got an I/O error from its bufio.Scanner while reading the downloaded checksums.txt — i.e. the manifest bytes were malformed in a way the scanner surfaced as an error, classically a line longer than the 64KB scanner buffer limit.

Source

Thrown at server/internal/cli/update.go:207

func parseChecksumManifest(manifest []byte, assetName string) (string, error) {
	scanner := bufio.NewScanner(bytes.NewReader(manifest))
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		fields := strings.Fields(line)
		// GoReleaser's default separator is two spaces; some tools use one
		// or pad with tabs. strings.Fields handles all of those at once.
		if len(fields) < 2 {
			continue
		}
		if fields[1] == assetName {
			return strings.ToLower(fields[0]), nil
		}
	}
	if err := scanner.Err(); err != nil {
		return "", fmt.Errorf("read checksum manifest: %w", err)
	}
	return "", fmt.Errorf("checksum for %q not found in manifest", assetName)
}

// verifyAssetSHA256 returns nil when the SHA-256 of data matches the lowercase
// hex expected value, or an error otherwise. The error includes both digests
// so a corrupted asset is diagnosable from the log without re-downloading.
func verifyAssetSHA256(data []byte, expectedHex, assetName string) error {
	if expectedHex == "" {
		return fmt.Errorf("empty expected checksum for %q", assetName)
	}
	sum := sha256.Sum256(data)
	actual := hex.EncodeToString(sum[:])
	if !strings.EqualFold(actual, expectedHex) {
		return fmt.Errorf("checksum mismatch for %q: expected %s, got %s", assetName, expectedHex, actual)
	}
	return nil
}

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Download checksums.txt manually and inspect it — verify it is plain '<sha256> <filename>' lines
  2. Re-fetch the release from the official repo to rule out mirror/proxy corruption
  3. If you generate the manifest, ensure one checksum per line with standard formatting
  4. Re-publish the release with a correctly generated manifest
Defensive patterns

Strategy: try-catch

Validate before calling

if len(manifest) > 0 && bytes.ContainsRune(manifest[:min(len(manifest),1024)], '<') {
	// looks like an HTML error page, not a checksum manifest; refetch
}

Try / catch

sum, err := cli.ParseChecksumManifest(manifest, assetName) // or equivalent
if err != nil && strings.Contains(err.Error(), "read checksum manifest") {
	// scanner-level failure: refetch the manifest once, then give up
}

Prevention

When it happens

Trigger: A checksums.txt containing an extremely long line (generated garbage, HTML error page saved as the manifest, or a binary blob uploaded under the checksums.txt name) makes bufio.Scanner return ErrTooLong.

Common situations: A proxy or mirror serving an HTML login page in place of checksums.txt; corrupted download truncation producing one massive line; a misconfigured release job concatenating binaries into the manifest.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/4da8a45a0a0aa4c1. Report an issue: GitHub.