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
- Fix the wrapped error's root cause: grant dst credentials s3:GetObject/Head permission or correct IAM policy.
- Retry the sync — transient destination 5xx/throttle errors usually clear.
- Reduce --threads or add rate limiting if the destination is throttling Head requests.
- 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
- Pre-flight a Head probe against the destination with the sync credentials.
- Grant s3:GetObject/HeadObject (or equivalent) on the destination.
- Throttle sync concurrency if the destination throttles Head requests.
- Validate endpoint/region/proxy settings before long syncs.
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
- closed
- errDirSuffix
- ErrSkipped
- the content of the multipart upload file is incorrect
- expect owner nobody but got %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/d786169d0f77e269.
Report an issue: GitHub.