juicedata/juicefs · error
checksums of copied object %s don't match
Error message
checksums of copied object %s don't match
What it means
Raised by checkSum during sync when --check-all or --check-new is enabled: after copying, the checksum of the destination object does not match the source's (MD5/content checksum comparison via srcChksum). It means the copy completed but the content verified as different.
Source
Thrown at pkg/sync/sync.go:1194
if err = copyLink(src, dst, key); err != nil {
logger.Errorf("copy link %s failed: %s", key, err)
}
} else {
srcChksum, err = copyData(src, dst, key, obj.Size(), obj.Mtime(), config.CheckAll || config.CheckNew, uploads)
}
if errors.Is(err, utils.ErrExtlink) {
logger.Warnf("Skip external link %s: %s", key, err)
err = utils.ErrSkipped
}
if err == nil && config.CheckChange {
err = checkChange(src, dst, obj, key, config)
}
if err == nil && (config.CheckAll || config.CheckNew) {
var equal bool
if equal, err = checkSum(src, dst, key, &srcChksum, obj, config); err == nil && !equal {
err = fmt.Errorf("checksums of copied object %s don't match", key)
}
}
if err == nil {
if mc, ok := dst.(object.MtimeChanger); ok {
if err = mc.Chtimes(obj.Key(), obj.Mtime()); err != nil && !errors.Is(err, utils.ErrNotSUP) {
logger.Warnf("Update mtime of %s: %s", key, err)
}
}
if config.Perms {
copyPerms(dst, obj, config)
}
copied.Increment()
} else if errors.Is(err, utils.ErrSkipped) {
skipped.Increment()
} else {
failed.Increment()
logger.Errorf("Failed to copy object %s: %s", key, err)
taskErr = errView on GitHub (pinned to c9a67b23e8)
Solutions
- Rerun sync for the object — a transient concurrent modification usually resolves; the mismatching object is typically overwritten on the next pass.
- Verify the destination backend does not transform content (disable transparent compression/encryption gateways during the check).
- Check for concurrent writers to the source and pause them, or exclude volatile keys from the sync.
- If using caching in the source client, clear/refresh caches and re-verify.
- Report persistent mismatches as a possible backend bug; check object ETags manually against both stores.
Example fix
// rerun sync with checks dstObj, _ := dst.Head(ctx, key) _ = dst.Put(ctx, key, nil, body) // re-copy on mismatch // then re-run: juicefs sync --check-all src dst
Defensive patterns
Strategy: retry
Validate before calling
// verify checksums manually after sync with --check-all
srcMD5, _ := md5OfFile(src, key)
dstMD5, _ := dstHeadETag(dst, key)
if srcMD5 != dstMD5 { log.Printf("mismatch on %s, will recopy", key) } Try / catch
err := runSync(checkAll=true)
if err != nil && strings.Contains(err.Error(), "checksums of copied object") {
logger.Warnf("checksum mismatch, recopying: %v", err)
return deleteAndRecopy(extractKey(err))
} Prevention
- Run sync twice; checksum mismatches from concurrent writes resolve on a later pass.
- Pause writers on the source when using --check-all/--check-new.
- Disable destination-side content transformations (compression gateways, etc.).
- Spot-check ETags/MD5s between stores after large syncs.
When it happens
Trigger: sync runs with --check-all or --check-new; after copy, checkSum reads/compares checksums (e.g. source MD5 vs destination) and they differ; the error is then returned from writeFiles for that key.
Common situations: Source object modified concurrently between read and checksum computation; destination backend corrupting or transforming data; syncing with a destination that doesn't preserve content byte-for-byte (e.g. compressed/gateway-transformed objects); interrupted/stale cache returning wrong content.
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/d910e51d21a9960a.
Report an issue: GitHub.