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

  1. 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).
  2. Check the cache disk with fsck/SMART for hardware errors and replace or repair a failing disk.
  3. Reduce risk of partial writes: ensure clean shutdown, enable fsync-backed storage, or move the cache to a more reliable volume.
  4. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/d4e965f03fbdf8cc. Report an issue: GitHub.