{"record":{"id":"d4e965f03fbdf8cc","repo":"juicedata/juicefs","slug":"data-checksum-d-expect-d","errorCode":null,"errorMessage":"data checksum %d != expect %d","messagePattern":"data checksum (.+?) != expect (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/chunk/disk_cache_file.go","lineNumber":260,"sourceCode":"\t\t}\n\t}\n\t// now rb contains the data to check\n\tlength := len(rb)\n\tbuf := utils.NewBuffer(uint32((length-1)/csBlock+1) * 4)\n\tif _, err = cf.File.ReadAt(buf.Bytes(), int64(cf.length+ioff*4)); err != nil {\n\t\tlogger.Warnf(\"Read checksum of data length %d checksum offset %d: %s\", length, cf.length+ioff*4, err)\n\t\treturn\n\t}\n\tfor start, end := 0, 0; start < length; start = end {\n\t\tend = start + csBlock\n\t\tif end > length {\n\t\t\tend = length\n\t\t}\n\t\tsum := crc32.Checksum(rb[start:end], crc32c)\n\t\texpect := buf.Get32()\n\t\tlogger.Debugf(\"Cache file read data start %d end %d checksum %d, expected %d\", start, end, sum, expect)\n\t\tif sum != expect {\n\t\t\terr = fmt.Errorf(\"data checksum %d != expect %d\", sum, expect)\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n","sourceCodeStart":242,"sourceCodeEnd":266,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/chunk/disk_cache_file.go#L242-L266","documentation":"When reading a cached disk block via ReadAt in pkg/chunk/disk_cache_file.go, JuiceFS verifies each record with a CRC32C checksum stored alongside the data. If the recomputed checksum of the on-disk bytes does not match the expected value read from the cache header, it returns 'data checksum %d != expect %d' and stops reading, treating the cache entry as corrupt.","triggerScenarios":"Calling cache.ReadAt (via DiskCache.load during block reads) on a cache file whose data bytes were corrupted on disk, partially written before a crash/power loss, truncated, or whose internal record header lengths are wrong so `start`/`end` slice a misaligned region.","commonSituations":"Disk corruption or bit rot on cache SSDs; host machine lost power mid-write to the cache file; external tampering with the cache directory (e.g. rsync/migration tools moving files); bugs or version skew from earlier cache format changes; running out of disk space causing partial writes.","solutions":["Delete the corrupt cache entry / whole cache directory and let JuiceFS re-download blocks (e.g. remove the offending file under the cache dir or run `juicefs gc` / restart with a fresh cache dir).","Check the cache disk with fsck/SMART for hardware errors and replace or repair a failing disk.","Reduce risk of partial writes: ensure clean shutdown, enable fsync-backed storage, or move the cache to a more reliable volume.","If reproducible after a JuiceFS upgrade, report with version info; check release notes for cache-format changes and clear old-format caches."],"exampleFix":"// before\nrb := make([]byte, ...)\n// blindly reusing a corrupted cache entry\n\n// after\nif err := cache.ReadAt(buf, offset); err != nil {\n    logger.Warnf(\"cache read failed: %v, fallback to object storage\", err)\n    data, err = store.Read(block) // re-fetch and rewrite cache\n}","handlingStrategy":"fallback","validationCode":"// check cache dir health before mounting\nif _, err := os.Stat(cacheDir); err != nil { ensureDir(cacheDir) }\n// monitor disk: smartctl -H /dev/sdX","typeGuard":null,"tryCatchPattern":"if err := cache.ReadAt(buf, off); err != nil {\n    logger.Warnf(\"cache corrupt: %v; refetching from storage\", err)\n    cache.Remove(entry)\n    data, err = store.Read(block) // fallback path\n}","preventionTips":["Monitor cache disk SMART/fsck status regularly","Always shut down clients cleanly; avoid power loss","Clear cache dirs after JuiceFS version upgrades with cache-format changes","Alert on this error in logs — it means on-disk corruption, not a caller bug"],"tags":["disk-cache","checksum","corruption","chunk"],"backgroundTag":"checksum-mismatch","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}