golang/go · error · entryNotFoundError

negative size

Error message

negative size

What it means

The size field in the cache entry header was successfully parsed as a decimal integer but the value is negative. The entry format space-pads the size to 20 bytes, and the parser strips leading spaces then calls strconv.ParseInt. A valid cache entry must have a non-negative output size, so a negative value means the size field bytes are corrupted.

Source

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

	etime, entry := entry[1:1+20], entry[1+20:]
	var buf [HashSize]byte
	if _, err := hex.Decode(buf[:], eid); err != nil {
		return missing(fmt.Errorf("decoding ID: %v", err))
	} else if buf != id {
		return missing(errors.New("mismatched ID"))
	}
	if _, err := hex.Decode(buf[:], eout); err != nil {
		return missing(fmt.Errorf("decoding output ID: %v", err))
	}
	i := 0
	for i < len(esize) && esize[i] == ' ' {
		i++
	}
	size, err := strconv.ParseInt(string(esize[i:]), 10, 64)
	if err != nil {
		return missing(fmt.Errorf("parsing size: %v", err))
	} else if size < 0 {
		return missing(errors.New("negative size"))
	}
	i = 0
	for i < len(etime) && etime[i] == ' ' {
		i++
	}
	tm, err := strconv.ParseInt(string(etime[i:]), 10, 64)
	if err != nil {
		return missing(fmt.Errorf("parsing timestamp: %v", err))
	} else if tm < 0 {
		return missing(errors.New("negative timestamp"))
	}

	c.markUsed(c.fileName(id, "a"))

	return Entry{buf, size, time.Unix(0, tm)}, nil
}

// GetFile looks up the action ID in the cache and returns

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Run go clean -cache to purge corrupt entries
  2. Verify all builds sharing the cache use the same Go version
  3. Run disk diagnostics (SMART, fsck) if corruption recurs
  4. Move GOCACHE to more reliable storage

Example fix

// before: corrupt size field in cache entry
// $ go build ./... # fails with 'cache entry not found: negative size'

// after: clean cache
// $ go clean -cache && go build ./...
Defensive patterns

Strategy: try-catch

Validate before calling

// No pre-check can predict field-level corruption.
// Ensure hardware reliability and cache hygiene instead.
// Consider GOCACHE="" to disable caching for debugging.

Type guard

func isNegativeSize(err error) bool {
    return err != nil && strings.Contains(err.Error(), "negative size")
}

Try / catch

// entry, err := cache.Get(id)
// if err != nil {
//     // Negative size — corrupt size field. Rebuild output.
//     output = rebuild()
// }

Prevention

When it happens

Trigger: DiskCache.get(id) parses the 20-byte space-padded size field (esize) with strconv.ParseInt(s, 10, 64) after stripping leading spaces. The parse succeeds but size < 0.

Common situations: Byte-level corruption specifically in the size field region of the entry file; a different Go version with a different entry format writing to the same cache; storage errors affecting the specific disk sectors holding these bytes.

Related errors


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