valyala/fasthttp · error

seek is not implemented

Error message

seek is not implemented

What it means

compressFileNolock, after compressing a file, needs to rewind the original file to the start with io.Seeker before re-reading it to write the compressed variant. If the opened fs.File lacks Seek, compression aborts with 'seek is not implemented'.

Source

Thrown at fs.go:1831

		}
		releaseStacklessGzipWriter(zw, CompressDefaultCompression)
	case "zstd":
		zw := acquireStacklessZstdWriter(w, CompressZstdDefault)
		_, err = copyZeroAlloc(zw, f)
		if errf := zw.Flush(); err == nil {
			err = errf
		}
		releaseStacklessZstdWriter(zw, CompressZstdDefault)
	}
	defer func() { _ = f.Close() }()

	if err != nil {
		return nil, fmt.Errorf("error when compressing file %q: %w", filePath, err)
	}

	seeker, ok := f.(io.Seeker)
	if !ok {
		return nil, errors.New("seek is not implemented")
	}
	if _, err = seeker.Seek(0, io.SeekStart); err != nil {
		return nil, err
	}

	ext := fileExtension(fileInfo.Name(), false, h.compressedFileSuffixes[fileEncoding])
	contentType := mime.TypeByExtension(ext)
	if contentType == "" {
		data, err := readFileHeader(f, false, fileEncoding)
		if err != nil {
			return nil, fmt.Errorf("cannot read header of the file %q: %w", fileInfo.Name(), err)
		}
		contentType = http.DetectContentType(data)
	}

	dirIndex := w.B
	lastModified := fileInfo.ModTime()
	ff := &fsFile{

View on GitHub (pinned to c96f600972)

Solutions

  1. Make the returned fs.File implement io.Seeker (wrap with a seekable backing store)
  2. Serve files backed by *os.File when compression is enabled
  3. Disable Compress for handlers serving non-seekable sources
  4. Compress content yourself out-of-band and serve the pre-compressed file with the expected compressed suffix

Example fix

// before
return &streamFile{rc: resp.Body} // not a Seeker
// after
f, err := os.CreateTemp("", "dl-")
io.Copy(f, resp.Body)
f.Seek(0, io.SeekStart)
return f, nil
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := file.(io.Seeker); !ok {
    // compression requires seekability; disable Compress or buffer the file
}

Type guard

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

Try / catch

f, err := openCompressed(path)
if err != nil && strings.Contains(err.Error(), "seek is not implemented") {
    // serve uncompressed via plain handler
}

Prevention

When it happens

Trigger: Enabling compression (Compress=true or per-encoding compressedFileSuffixes) on fsHandler and serving a file whose fs.File implementation is not an io.Seeker.

Common situations: Custom fs.File implementations wrapping streams (HTTP downloads, pipes) under a compressing static handler; memory-mapped or generated file substitutes lacking Seek.

Related errors


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