juicedata/juicefs · error
src read: %s
Error message
src read: %s
What it means
io.ReadFull on the SOURCE range reader returned fewer bytes than requested (usually io.ErrUnexpectedEOF) or another read error. The source object delivered less data than its reported size/range, so comparison cannot proceed.
Source
Thrown at pkg/sync/sync.go:576
in2, err := dst.Get(ctx, key, offset, length)
if err != nil {
return fmt.Errorf("dest get: %s", err)
}
defer in2.Close()
buf := bufPool.Get().(*[]byte)
defer bufPool.Put(buf)
buf2 := bufPool.Get().(*[]byte)
defer bufPool.Put(buf2)
for left := int(length); left > 0; left -= bufferSize {
bs := bufferSize
if left < bufferSize {
bs = left
}
*buf = (*buf)[:bs]
*buf2 = (*buf2)[:bs]
if _, err = io.ReadFull(in, *buf); err != nil {
return fmt.Errorf("src read: %s", err)
}
if _, err = io.ReadFull(in2, *buf2); err != nil {
return fmt.Errorf("dest read: %s", err)
}
if !bytes.Equal(*buf, *buf2) {
return fmt.Errorf("bytes not equal")
}
}
return nil
}
func compObjBinary(src, dst object.ObjectStorage, key string, abort chan struct{}, obj object.Object) (bool, error) {
var err error
if obj.Size() < maxBlock {
err = compObjPartBinary(src, dst, key, abort, 0, obj.Size())
} else {
n := int((obj.Size()-1)/defaultPartSize) + 1
errs := make(chan error, n)View on GitHub (pinned to c9a67b23e8)
Solutions
- Retry the comparison; the wrapped io error tells whether it was UnexpectedEOF (truncation) or a connection error.
- Exclude concurrently-written keys from the sync or re-copy the object after the writer finishes.
- Verify object size on src matches what listing reported; if not, re-sync the object.
- Check for proxy/firewall idle-timeout killing long reads; reduce part size.
Defensive patterns
Strategy: retry
Validate before calling
// verify reported size before reading
info, err := src.Head(ctx, key)
if err != nil || info.Size() < offset+length {
return fmt.Errorf("source size changed or too small for %s", key)
} Try / catch
if err := comparePart(...); err != nil {
if strings.Contains(err.Error(), "src read: unexpected EOF") {
return retryCompareWithBackoff(3)
}
return err
} Prevention
- Avoid syncing keys that writers are actively modifying
- Reduce part size on flaky networks to shorten individual reads
- Retry transient truncation errors
- Re-list objects when size mismatches are detected
When it happens
Trigger: Object size changed between HEAD/Listing and the ranged GET; truncated upload on the source; connection dropped mid-read; backend returning short reads.
Common situations: Syncing live buckets where a writer is uploading/overwriting the object concurrently; unstable networks; providers with eventual-consistency quirks.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to read checkpoint: %w
- open %s
- create %s
- Unable to skip %s bytes (position=%s, fileSize=%s): %s
- write
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/2533b2cdb27512bb.
Report an issue: GitHub.