juicedata/juicefs · error

check %s in %s: %s

Error message

check %s in %s: %s

What it means

Wraps a failure to verify the copied object on the DESTINATION during checkChange: dst.Head failed with a non-not-exist error. Sync could not confirm the copy landed correctly, so it reports 'check <key> in <dst>: <err>'.

Source

Thrown at pkg/sync/sync.go:1255

			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
	}
	return try(3, func() (err error) {
		// TODO: use relative path based on option
		if err := dst.(object.SupportSymlink).Symlink(p, key); err != nil {
			if info, err := dst.Head(ctx, key); err == nil && info.IsSymlink() {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Fix the wrapped error's root cause: grant dst credentials s3:GetObject/Head permission or correct IAM policy.
  2. Retry the sync — transient destination 5xx/throttle errors usually clear.
  3. Reduce --threads or add rate limiting if the destination is throttling Head requests.
  4. Verify dst endpoint/region configuration (correct URL, no stale proxy settings).

Example fix

# grant Head access on destination
aws s3api put-bucket-policy --bucket dst --policy file://allow-head.json
# then rerun
juicefs sync src dst --check-all
Defensive patterns

Strategy: retry

Validate before calling

// verify destination Head permission before sync
_, err := dst.Head(ctx, probeKey)
if err != nil && !errors.Is(err, os.ErrNotExist) {
  return fmt.Errorf("dst Head permission/endpoint problem: %w", err)
}

Try / catch

if err := sync(...); err != nil {
  if strings.Contains(err.Error(), fmt.Sprintf("check %s in", key)) && !strings.Contains(err.Error(), "was removed") {
    return retryWithBackoff(sync, 3) // transient dst Head failure
  }
  return err
}

Prevention

When it happens

Trigger: After src Head confirms the object is unchanged, dst.Head(ctx, key) returns an error other than os.ErrNotExist (permission denied, timeout, 5xx, throttling), producing this wrapped error.

Common situations: Destination credentials lack read (Head) permission even though writes succeeded; destination throttling under heavy sync load; destination endpoint temporarily unavailable; proxy/firewall interference.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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