AlistGo/alist · error
stream RangeRead did not get all data in peek, expect =%d ,a
Error message
stream RangeRead did not get all data in peek, expect =%d ,actual =%d
What it means
In stream File.RangeRead, when no cached io.ReaderAt exists and size fits under InMemoryBufMaxSizeBytes, the head of the file is read into a peek buffer with io.ReadFull. This defensive check fires if ReadFull returns err==nil but fewer bytes than requested — a short read without error, which normal Readers should not produce.
Source
Thrown at internal/stream/stream.go:136
httpRange.Length = f.GetSize() - httpRange.Start
}
size := httpRange.Start + httpRange.Length
if f.peekBuff != nil && size <= int64(f.peekBuff.Len()) {
return io.NewSectionReader(f.peekBuff, httpRange.Start, httpRange.Length), nil
}
var cache io.ReaderAt = f.GetFile()
if cache == nil {
if size <= InMemoryBufMaxSizeBytes {
bufSize := min(size, f.GetSize())
// 使用bytes.Buffer作为io.CopyBuffer的写入对象,CopyBuffer会调用Buffer.ReadFrom
// 即使被写入的数据量与Buffer.Cap一致,Buffer也会扩大
buf := make([]byte, bufSize)
n, err := io.ReadFull(f.Reader, buf)
if err != nil {
return nil, err
}
if n != int(bufSize) {
return nil, fmt.Errorf("stream RangeRead did not get all data in peek, expect =%d ,actual =%d", bufSize, n)
}
f.peekBuff = bytes.NewReader(buf)
f.Reader = io.MultiReader(f.peekBuff, f.Reader)
cache = f.peekBuff
} else {
var err error
cache, err = f.CacheFullInTempFile()
if err != nil {
return nil, err
}
}
}
return io.NewSectionReader(cache, httpRange.Start, httpRange.Length), nil
}
var _ model.FileStreamer = (*SeekableStream)(nil)
var _ model.FileStreamer = (*FileStream)(nil)
View on GitHub (pinned to 843d9dc814)
Solutions
- Verify the file's reported size matches the actual content size (re-stat the file on the remote)
- Check the driver's Link/Reader implementation for a wrapper that hides ErrUnexpectedEOF
- If the size is unreliable, use the temp-file caching path by exceeding InMemoryBufMaxSizeBytes or fix GetSize() in the driver
Defensive patterns
Strategy: try-catch
Try / catch
data, err := file.RangeRead(ctx, http_range.Range{Start: 0, Length: size})
if err != nil {
if strings.Contains(err.Error(), "did not get all data in peek") {
// size metadata is wrong: re-stat the remote object and retry, or full-cache to temp file
}
} Prevention
- Ensure driver GetSize() returns the true content length
- Do not wrap readers in ways that swallow ErrUnexpectedEOF
- Add driver unit tests asserting ReadFull(n) == n for declared sizes
When it happens
Trigger: An underlying model.File stream (usually a link/HTTP or driver reader) that returns io.EOF early but is wrapped so ReadFull reports success with n < bufSize — essentially a misbehaving driver reader or a size/length mismatch between GetSize() and actual readable data.
Common situations: A storage driver reporting a wrong file size (metadata larger than real content), or a Reader wrapper that swallows an EOF short-read error.
Related errors
- [doubao_new] short read: seq=%d want=%d got=%d
- failed to read response body: %v
- read on closed file
- can't create RangeReadCloser since URL is empty in link
- http request failure, err:%s
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/e5fce4d0ee9046e6.
Report an issue: GitHub.