golang/go · error · entryNotFoundError

bad checksum

Error message

bad checksum

What it means

In GetBytes(), the SHA-256 hash of the output data read from disk does not match the OutputID stored in the cache entry. This is a content-integrity checksum that catches silent data corruption in the output file — the file exists and has the right size but its bytes have changed. The OutputID IS the SHA-256 hash of the output, so any mismatch means corruption.

Source

Thrown at src/cmd/go/internal/cache/cache.go:291

		return "", Entry{}, &entryNotFoundError{Err: err}
	}
	if info.Size() != entry.Size {
		return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")}
	}
	return file, entry, nil
}

// GetBytes looks up the action ID in the cache and returns
// the corresponding output bytes.
// GetBytes should only be used for data that can be expected to fit in memory.
func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) {
	entry, err := c.Get(id)
	if err != nil {
		return nil, entry, err
	}
	data, _ := os.ReadFile(c.OutputFile(entry.OutputID))
	if sha256.Sum256(data) != entry.OutputID {
		return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")}
	}
	return data, entry, nil
}

// GetMmap looks up the action ID in the cache and returns
// the corresponding output bytes.
// GetMmap should only be used for data that can be expected to fit in memory.
// The boolean result indicates whether the file was opened.
// If it is true, the caller should avoid attempting
// to write to the file on Windows, because Windows locks
// the open file, and writes to it will fail.
func GetMmap(c Cache, id ActionID) ([]byte, Entry, bool, error) {
	entry, err := c.Get(id)
	if err != nil {
		return nil, entry, false, err
	}
	md, opened, err := mmap.Mmap(c.OutputFile(entry.OutputID))
	if err != nil {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Run go clean -cache to purge corrupted output files
  2. Run disk SMART diagnostics (smartctl) and memory tests (memtest86)
  3. Move cache to more reliable storage (SSD vs aging HDD, RAID)
  4. If corruption recurs frequently, investigate hardware health comprehensively

Example fix

// before: checksum mismatch in cached output
// $ go build ./... # fails with 'cache entry not found: bad checksum'

// after: clean cache and check hardware
// $ go clean -cache && go build ./...
// $ smartctl -H /dev/sda  # if issue recurs, check disk health
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify output integrity by computing SHA-256 before trusting cached data.
import "crypto/sha256"

func verifyOutputChecksum(path string, expected cache.OutputID) error {
    data, err := os.ReadFile(path)
    if err != nil {
        return err
    }
    actual := sha256.Sum256(data)
    if actual != expected {
        return fmt.Errorf("checksum mismatch for %s", path)
    }
    return nil
}

Type guard

func isBadChecksum(err error) bool {
    return err != nil && strings.Contains(err.Error(), "bad checksum")
}

Try / catch

// data, entry, err := cache.GetBytes(c, id)
// if err != nil {
//     // Bad checksum — output data silently corrupted.
//     // Rebuild the output from source.
//     data = rebuild()
// }
//
// // GetBytes already verifies the checksum internally,
// // so if it returns nil error, the data is verified.

Prevention

When it happens

Trigger: GetBytes(c, id) reads the output file bytes via os.ReadFile, computes sha256.Sum256(data), and compares against entry.OutputID. The comparison fails — the hashes differ.

Common situations: Silent disk corruption (bit rot on aging storage); failing storage hardware (bad sectors, controller errors); cosmic ray bit-flips on unreliable hardware; external modification of cached output files; RAM errors corrupting data during read.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/cf3882357520e5d9. Report an issue: GitHub.