AlistGo/alist · error
offset out of range
Error message
offset out of range
What it means
When a stream cannot be memory-mapped, RangeReadReadAtSeeker is used and its RangeRead method validates the requested start offset: it must be within [0, size]. An offset beyond the stream size (or negative) returns 'offset out of range' before any network read is attempted. This is a local sanity check, so it fails instantly rather than after a round trip.
Source
Thrown at internal/stream/stream.go:432
r.ss.Closers.Add(r.headCache)
}
}
func NewReadAtSeeker(ss *SeekableStream, offset int64, forceRange ...bool) (SStreamReadAtSeeker, error) {
if ss.mFile != nil {
_, err := ss.mFile.Seek(offset, io.SeekStart)
if err != nil {
return nil, err
}
return &FileReadAtSeeker{ss: ss}, nil
}
r := &RangeReadReadAtSeeker{
ss: ss,
masterOff: offset,
}
if offset != 0 || utils.IsBool(forceRange...) {
if offset < 0 || offset > ss.GetSize() {
return nil, errors.New("offset out of range")
}
_, err := r.getReaderAtOffset(offset)
if err != nil {
return nil, err
}
} else {
rc := &readerCur{reader: ss, cur: offset}
r.readers = append(r.readers, rc)
}
return r, nil
}
func NewMultiReaderAt(ss []*SeekableStream) (readerutil.SizeReaderAt, error) {
readers := make([]readerutil.SizeReaderAt, 0, len(ss))
for _, s := range ss {
ra, err := NewReadAtSeeker(s, 0)
if err != nil {
return nil, errView on GitHub (pinned to 843d9dc814)
Solutions
- Re-validate the offset against the current stream size before reading
- Refresh the cached listing/size for the object and retry
- Fix client-side range math, especially end-anchored ranges (bytes=-N) converted to absolute offsets
Example fix
// before
r, err := ss.RangeRead(offset, length)
// after
if offset < 0 || offset > ss.GetSize() {
return nil, fmt.Errorf("bad offset %d for size %d", offset, ss.GetSize())
}
r, err := ss.RangeRead(offset, length) Defensive patterns
Strategy: validation
Validate before calling
// Before a ranged read
size := ss.GetSize()
if offset < 0 || offset > size {
return fmt.Errorf("offset %d out of range for size %d", offset, size)
} Type guard
func validOffset(off int64, size int64) bool {
return off >= 0 && off <= size
} Try / catch
r, err := ss.RangeRead(offset, length)
if err != nil && strings.Contains(err.Error(), "offset out of range") {
// refresh cached size metadata and recompute the range
refreshListing()
} Prevention
- Refresh object size metadata before serving range requests
- Clamp client Range headers to the current size
- Compute end-anchored ranges (bytes=-N) with care: offset = size - N
When it happens
Trigger: Calling the stream's RangeRead/section reader with an offset > ss.GetSize() or < 0 — e.g. a client sending a Range header like 'bytes=999999999999-' on a smaller file, or code computing an offset from stale size metadata.
Common situations: Cached file size is smaller than the real file (stale listing) so a valid-looking seek exceeds the cached bound; clients issuing end-anchored ranges computed incorrectly; off-by-one after truncation.
Related errors
- invalid seek: negative position
- can't create RangeReadCloser since URL is empty in link
- paths is required
- remote_path is required
- chunk_size must be positive
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/69655c7f863720ea.
Report an issue: GitHub.