ipfs/kubo · error

empty or malformed .sha512 file

Error message

empty or malformed .sha512 file

What it means

downloadAndVerifySHA512 parses the .sha512 sidecar expecting standard sha512sum format (`<hex> <filename>`). If the downloaded checksum content has no fields at all — an empty body or pure whitespace — the parser cannot extract the expected hash and throws this error.

Source

Thrown at core/commands/update_github.go:250

	if int64(len(data)) > maxDownloadSize {
		return nil, fmt.Errorf("download exceeds maximum size of %d bytes", maxDownloadSize)
	}
	return data, nil
}

// downloadAndVerifySHA512 downloads the .sha512 sidecar file for the given
// archive URL and verifies the archive data against it.
func downloadAndVerifySHA512(ctx context.Context, data []byte, archiveURL string) error {
	sha512URL := archiveURL + ".sha512"
	checksumData, err := downloadAsset(ctx, sha512URL)
	if err != nil {
		return fmt.Errorf("downloading checksum file: %w", err)
	}

	// Parse "<hex>  <filename>\n" format (standard sha512sum output).
	fields := strings.Fields(string(checksumData))
	if len(fields) < 1 {
		return fmt.Errorf("empty or malformed .sha512 file")
	}
	wantHex := fields[0]

	return verifySHA512(data, wantHex)
}

// verifySHA512 checks that data matches the given hex-encoded SHA-512 hash.
func verifySHA512(data []byte, wantHex string) error {
	want, err := hex.DecodeString(wantHex)
	if err != nil {
		return fmt.Errorf("invalid hex in SHA-512 checksum: %w", err)
	}
	got := sha512.Sum512(data)
	if !bytes.Equal(got[:], want) {
		return fmt.Errorf("SHA-512 mismatch: expected %s, got %x", wantHex, got[:])
	}
	return nil
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Retry from a different network to rule out proxy interception
  2. Inspect the sidecar manually: `curl -s <archive-url>.sha512` — it must contain a hex digest and filename
  3. If the published .sha512 file is genuinely empty, report the broken release artifact to kubo maintainers
  4. Download the archive and checksum manually and verify with `sha512sum -c` as a workaround
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check the sidecar content before trusting the updater
body, err := fetch(archiveURL + ".sha512")
if err != nil {
	return err
}
fields := strings.Fields(string(body))
if len(fields) < 1 || len(fields[0]) != 128 {
	return fmt.Errorf("checksum sidecar empty or not sha512 hex — network/proxy interference suspected")
}

Try / catch

if err := runUpdate(); err != nil {
	if strings.Contains(err.Error(), "empty or malformed .sha512") {
		// compare with the published checksum manually
		log.Print("verify manually: curl -s <archive>.sha512 | sha512sum -c")
	}
	return err
}

Prevention

When it happens

Trigger: The .sha512 URL returns HTTP 200 with an empty or whitespace-only body: a proxy/interception layer returned a blank 200, GitHub served a zero-byte object, or the sidecar was uploaded empty.

Common situations: Captive portals or middleboxes returning empty 200 responses; a corrupted upload in the release; misbehaving proxies that silently replace content with empty bodies while keeping status 200.

Understand the failure class

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/0ea49495563ff707. Report an issue: GitHub.