{"record":{"id":"102e408273783cea","repo":"golang/go","slug":"invalid-header","errorCode":null,"errorMessage":"invalid header","messagePattern":"invalid header","errorType":"exception","errorClass":"entryNotFoundError","httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/cache/cache.go","lineNumber":222,"sourceCode":"\t}\n\tf, err := os.Open(c.fileName(id, \"a\"))\n\tif err != nil {\n\t\treturn missing(err)\n\t}\n\tdefer f.Close()\n\tentry := make([]byte, entrySize+1) // +1 to detect whether f is too long\n\tif n, err := io.ReadFull(f, entry); n > entrySize {\n\t\treturn missing(errors.New(\"too long\"))\n\t} else if err != io.ErrUnexpectedEOF {\n\t\tif err == io.EOF {\n\t\t\treturn missing(errors.New(\"file is empty\"))\n\t\t}\n\t\treturn missing(err)\n\t} else if n < entrySize {\n\t\treturn missing(errors.New(\"entry file incomplete\"))\n\t}\n\tif entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\\n' {\n\t\treturn missing(errors.New(\"invalid header\"))\n\t}\n\teid, entry := entry[3:3+hexSize], entry[3+hexSize:]\n\teout, entry := entry[1:1+hexSize], entry[1+hexSize:]\n\tesize, entry := entry[1:1+20], entry[1+20:]\n\tetime, entry := entry[1:1+20], entry[1+20:]\n\tvar buf [HashSize]byte\n\tif _, err := hex.Decode(buf[:], eid); err != nil {\n\t\treturn missing(fmt.Errorf(\"decoding ID: %v\", err))\n\t} else if buf != id {\n\t\treturn missing(errors.New(\"mismatched ID\"))\n\t}\n\tif _, err := hex.Decode(buf[:], eout); err != nil {\n\t\treturn missing(fmt.Errorf(\"decoding output ID: %v\", err))\n\t}\n\ti := 0\n\tfor i < len(esize) && esize[i] == ' ' {\n\t\ti++\n\t}","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/cache/cache.go#L204-L240","documentation":"The entry file has the correct size (exactly entrySize bytes) but its header bytes don't match the expected format 'v1 <hex-action-id> <hex-output-id> <size> <timestamp>\\n'. The code checks for the 'v1' prefix, space delimiters at specific offsets, and a trailing newline. A mismatch means the file content was corrupted despite having the right length.","triggerScenarios":"DiskCache.get(id) reads a full entrySize bytes (the valid-length case) but the header validation on entry[0], entry[1], entry[2], entry[3+hexSize], and other delimiter positions fails — wrong version marker, missing spaces, or wrong trailing byte.","commonSituations":"Byte-level corruption from bad RAM, disk errors, or filesystem bugs; a different Go toolchain version writing entries with a different format version to the same cache directory; cosmic ray bit-flips on unreliable hardware; manual editing of cache files.","solutions":["Run go clean -cache to purge all entries and rebuild","Run hardware diagnostics — memtest86 for RAM, SMART checks for disk health","Ensure a consistent Go version across all builds that share the same GOCACHE directory","Move the cache to more reliable storage if corruption recurs"],"exampleFix":"// before: corrupt header bytes in cache entry\n// $ go build ./... # fails with 'cache entry not found: invalid header'\n\n// after: clean cache and verify hardware\n// $ go clean -cache && go build ./...\n// $ smartctl -a /dev/sda  # check disk health if issue recurs","handlingStrategy":"try-catch","validationCode":"// Validate cache format compatibility before using a shared cache.\n// Check the Go version matches what created the cache.\nfunc checkCacheVersionCompat(cacheDir string) error {\n    // The cache log file records the Go version that created the cache\n    logPath := filepath.Join(cacheDir, \"log.txt\")\n    data, err := os.ReadFile(logPath)\n    if err != nil {\n        return nil // no log, assume fresh cache\n    }\n    currentVersion := runtime.Version()\n    if !bytes.Contains(data, []byte(currentVersion)) {\n        return fmt.Errorf(\"cache may be from a different Go version; run go clean -cache\")\n    }\n    return nil\n}","typeGuard":"func isInvalidHeader(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"invalid header\")\n}","tryCatchPattern":"// entry, err := cache.Get(id)\n// if err != nil {\n//     // Invalid header — corrupt or version-incompatible entry.\n//     // Rebuild the output from source.\n//     output = rebuild()\n// }","preventionTips":["Always run go clean -cache after upgrading to a new Go version","Never share GOCACHE across different Go versions or machines","Run periodic hardware diagnostics (memtest, SMART) to catch failing components","Store the cache on reliable local storage (SSD preferred over network mounts)"],"tags":["go","build-cache","corruption","disk-cache","header"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}