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

  1. Delete the destination object and rerun sync for that key so it is fully recopied.
  2. Check for concurrent writers to the same destination key and make the sync exclusive.
  3. Verify the destination backend's integrity (read back and checksum the object).
  4. 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

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


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