juicedata/juicefs · critical
copied %s size mismatch: original=%d, current=%d
Error message
copied %s size mismatch: original=%d, current=%d
What it means
Raised by checkChange after the source object was confirmed unchanged: a Head on the destination shows the copied object's size doesn't match the source's. The copy itself produced a wrong-size object — a data-integrity failure of dst.
Source
Thrown at pkg/sync/sync.go:1251
return nil // ignore symlink
}
if cur, err := src.Head(ctx, key); err == nil {
if !config.CheckAll && !config.CheckNew {
checked.Increment()
checkedBytes.IncrInt64(obj.Size())
}
equal := cur.Size() == obj.Size()
if equal && !cur.Mtime().Equal(obj.Mtime()) {
// Head of an object may not return the millisecond part of mtime as List
equal = cur.Mtime().Unix() == obj.Mtime().Unix() && cur.Mtime().UnixMilli()%1000 == 0
}
if !equal {
return fmt.Errorf("%s changed during sync. Original: size=%d, mtime=%s; Current: size=%d, mtime=%s",
cur.Key(), obj.Size(), obj.Mtime(), cur.Size(), cur.Mtime())
}
if dstObj, err := dst.Head(ctx, key); err == nil {
if cur.Size() != dstObj.Size() {
return fmt.Errorf("copied %s size mismatch: original=%d, current=%d", key, obj.Size(), dstObj.Size())
}
return nil
} else {
return fmt.Errorf("check %s in %s: %s", key, dst, err)
}
} else if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("object %s was removed during sync", key)
} else {
return fmt.Errorf("check %s in %s: %s", key, src, err)
}
}
func copyLink(src object.ObjectStorage, dst object.ObjectStorage, key string) error {
var p string
var err error
if p, err = src.(object.SupportSymlink).Readlink(key); err != nil {
return err
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Delete the destination object and rerun sync for that key so it is fully recopied.
- Check for concurrent writers to the same destination key and make the sync exclusive.
- Verify the destination backend's integrity (read back and checksum the object).
- If using a custom object.ObjectStorage, audit its Put/Head size accounting.
Example fix
# remove corrupt destination object and resync juicefs rm dst:bucket/key juicefs sync src dst --include key
Defensive patterns
Strategy: retry
Validate before calling
cur, err := dst.Head(ctx, key)
if err == nil && cur.Size() != expectedSize {
return fmt.Errorf("recopy needed for %s", key)
} Try / catch
if err := sync(...); err != nil && strings.Contains(err.Error(), "size mismatch") {
_ = dst.Delete(ctx, extractKey(err)) // remove corrupt copy
return sync(...) // full recopy
} Prevention
- Make syncs exclusive per destination key; no concurrent writers.
- Delete the mismatching destination object before rerunning sync.
- Audit custom object storage implementations for size accounting bugs.
- Read back and checksum large copies to catch backend corruption.
When it happens
Trigger: checkChange: cur (src Head) equals the originally listed object; then dst.Head succeeds but dstObj.Size() != cur.Size(), so the already-copied object has the wrong size.
Common situations: Destination backend truncating or appending data (flaky storage, quota effects, concurrent writers to the same destination key); a partially failed earlier copy left a short object that sync then considered copied; custom/broken object storage implementations reporting or storing wrong sizes.
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
- checksums of copied object %s don't match
- closed
- errDirSuffix
- ErrSkipped
- skip special file %s for jfs: %w
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/103e9f7a40bab9e2.
Report an issue: GitHub.