juicedata/juicefs · error
page is already released
Error message
page is already released
What it means
pageReader.ReadAt reports that the underlying page has already been released (its buffer returned to the pool) and can no longer be read. Reading from a released page would access freed/reused memory, so the reader refuses with this error instead.
Source
Thrown at pkg/chunk/page.go:120
}
func NewPageReader(p *Page) *pageReader {
p.Acquire()
return &pageReader{p, 0}
}
func (r *pageReader) Read(buf []byte) (int, error) {
n, err := r.ReadAt(buf, int64(r.off))
r.off += n
return n, err
}
func (r *pageReader) ReadAt(buf []byte, off int64) (int, error) {
if len(buf) == 0 {
return 0, nil
}
if r.p == nil {
return 0, errors.New("page is already released")
}
if int(off) == len(r.p.Data) {
return 0, io.EOF
}
n := copy(buf, r.p.Data[off:])
if n < len(buf) {
return n, io.EOF
}
return n, nil
}
func (r *pageReader) Close() error {
if r.p != nil {
r.p.Release()
r.p = nil
}
return nil
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Ensure the page is not released until all readers are done; extend the page's lifetime or take a reference before reading.
- Do not reuse a pageReader after release; obtain a new page/reader for subsequent reads.
- Check for double-release / early-release in the producer code that hands out the reader (e.g. in upload completion paths).
Example fix
// before r.p.Release() n, err := r.ReadAt(buf, 0) // error: page is already released // after n, err := r.ReadAt(buf, 0) r.p.Release()
Defensive patterns
Strategy: type-guard
Validate before calling
func canRead(r *chunk.PageReader) bool { return r != nil && !r.Released() } // if such an accessor exists; otherwise track release in owner code Type guard
func (r *pageReader) usable() bool { return r.p != nil } Try / catch
n, err := pr.ReadAt(buf, off)
if err != nil && err.Error() == "page is already released" {
return ErrPageReleased // propagate to owner to re-acquire page
} Prevention
- Release pages only after all ReadAt/Read calls finish
- Avoid sharing pageReader across goroutines after release
- Acquire a page reference before handing a reader to another component
When it happens
Trigger: Calling ReadAt (directly or via Read) on a pageReader whose page was released via r.p.Release() / a nil-out on release, or reusing a pageReader after its page lifetime ended (e.g. after an upload finished).
Common situations: Concurrent readers holding a pageReader after the owner released the page; retry logic reading a completed upload's page reader a second time.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- RangerPermissionChecker for volume: " + volName + " is alrea
- RangerPermissionChecker for volume: " + volName + " is alrea
- I/O operation on closed file.
- not supported
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/6ee33af155d6af9c.
Report an issue: GitHub.