valyala/fasthttp · error

must implement seek

Error message

must implement seek

What it means

bigFileReader.UpdateByteRange requires the underlying file handle to implement io.Seeker; if it doesn't (e.g. wrapped reader or unusual fs handle) it returns this error. Byte-range serving for large files depends on seeking directly in the file.

Source

Thrown at fs.go:760

}

func (ff *fsFile) decReadersCount() {
	ff.h.cacheManager.DecReadersCount(ff)
}

// bigFileReader attempts to trigger sendfile
// for sending big files over the wire.
type bigFileReader struct {
	f  fs.File
	ff *fsFile
	r  io.Reader
	lr io.LimitedReader
}

func (r *bigFileReader) UpdateByteRange(startPos, endPos int) error {
	seeker, ok := r.f.(io.Seeker)
	if !ok {
		return errors.New("must implement seek")
	}
	if _, err := seeker.Seek(int64(startPos), io.SeekStart); err != nil {
		return err
	}
	r.r = &r.lr
	r.lr.R = r.f
	r.lr.N = int64(endPos - startPos + 1)
	return nil
}

func (r *bigFileReader) Read(p []byte) (int, error) {
	return r.r.Read(p)
}

func (r *bigFileReader) WriteTo(w io.Writer) (int64, error) {
	if rf, ok := w.(io.ReaderFrom); ok {
		// fast path. Send file must be triggered
		return rf.ReadFrom(r.r)

View on GitHub (pinned to c96f600972)

Solutions

  1. Ensure the FileSystem returns *os.File (or another io.ReadSeeker) for large files
  2. Wrap the custom file type and implement io.Seeker (delegate to the real file)
  3. Fall back to small-file range handling (which uses memory) or serve the full file if seeking is impossible
  4. Fix test mocks to embed a Seeker implementation

Example fix

// before
type myFile struct{ r io.Reader }
fs := &fasthttp.FS{ ... } // returns myFile -> UpdateByteRange fails
// after
type myFile struct{ f *os.File }
func (m *myFile) Seek(offset int64, whence int) (int64, error) {
    return m.f.Seek(offset, whence)
}
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := file.(io.Seeker); !ok {
    return errors.New("file for bigFileReader must implement io.Seeker")
}

Type guard

func isSeekable(f fs.File) bool {
    _, ok := f.(io.Seeker)
    return ok
}

Try / catch

if err := r.UpdateByteRange(start, end); err != nil && err.Error() == "must implement seek" {
    // fall back to full-file serving or buffered reader
}

Prevention

When it happens

Trigger: Calling bigFileReader.UpdateByteRange (used by fasthttp's Range request handling for large files) when r.f was created from something that doesn't implement io.Seeker — for instance a custom FileSystem returning a non-seekable file wrapper.

Common situations: Custom fasthttp FS implementations returning os.File wrappers stripped of Seek; embedding the file in a network stream or compressed reader; mocking fs.File in tests with a type lacking Seek.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/a9e25dc719bd1322. Report an issue: GitHub.