juicedata/juicefs · error
data checksum %d != expect %d
Error message
data checksum %d != expect %d
What it means
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.
Source
Thrown at pkg/chunk/disk_cache_file.go:260
}
}
// now rb contains the data to check
length := len(rb)
buf := utils.NewBuffer(uint32((length-1)/csBlock+1) * 4)
if _, err = cf.File.ReadAt(buf.Bytes(), int64(cf.length+ioff*4)); err != nil {
logger.Warnf("Read checksum of data length %d checksum offset %d: %s", length, cf.length+ioff*4, err)
return
}
for start, end := 0, 0; start < length; start = end {
end = start + csBlock
if end > length {
end = length
}
sum := crc32.Checksum(rb[start:end], crc32c)
expect := buf.Get32()
logger.Debugf("Cache file read data start %d end %d checksum %d, expected %d", start, end, sum, expect)
if sum != expect {
err = fmt.Errorf("data checksum %d != expect %d", sum, expect)
break
}
}
return
}
View on GitHub (pinned to c9a67b23e8)
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.
Example fix
// before
rb := make([]byte, ...)
// blindly reusing a corrupted cache entry
// after
if err := cache.ReadAt(buf, offset); err != nil {
logger.Warnf("cache read failed: %v, fallback to object storage", err)
data, err = store.Read(block) // re-fetch and rewrite cache
} Defensive patterns
Strategy: fallback
Validate before calling
// check cache dir health before mounting
if _, err := os.Stat(cacheDir); err != nil { ensureDir(cacheDir) }
// monitor disk: smartctl -H /dev/sdX Try / catch
if err := cache.ReadAt(buf, off); err != nil {
logger.Warnf("cache corrupt: %v; refetching from storage", err)
cache.Remove(entry)
data, err = store.Read(block) // fallback path
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- The entry of the root inode was not found
- ErrFuncTimeout
- failed to read footer: %w
- writeend %s: %s
- write out of chunk boundary: %d > %d
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/d4e965f03fbdf8cc.
Report an issue: GitHub.