{"record":{"id":"1d22ceb27903dc9e","repo":"valyala/fasthttp","slug":"seek-is-not-implemented","errorCode":null,"errorMessage":"seek is not implemented","messagePattern":"seek is not implemented","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":1831,"sourceCode":"\t\t}\n\t\treleaseStacklessGzipWriter(zw, CompressDefaultCompression)\n\tcase \"zstd\":\n\t\tzw := acquireStacklessZstdWriter(w, CompressZstdDefault)\n\t\t_, err = copyZeroAlloc(zw, f)\n\t\tif errf := zw.Flush(); err == nil {\n\t\t\terr = errf\n\t\t}\n\t\treleaseStacklessZstdWriter(zw, CompressZstdDefault)\n\t}\n\tdefer func() { _ = f.Close() }()\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error when compressing file %q: %w\", filePath, err)\n\t}\n\n\tseeker, ok := f.(io.Seeker)\n\tif !ok {\n\t\treturn nil, errors.New(\"seek is not implemented\")\n\t}\n\tif _, err = seeker.Seek(0, io.SeekStart); err != nil {\n\t\treturn nil, err\n\t}\n\n\text := fileExtension(fileInfo.Name(), false, h.compressedFileSuffixes[fileEncoding])\n\tcontentType := mime.TypeByExtension(ext)\n\tif contentType == \"\" {\n\t\tdata, err := readFileHeader(f, false, fileEncoding)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot read header of the file %q: %w\", fileInfo.Name(), err)\n\t\t}\n\t\tcontentType = http.DetectContentType(data)\n\t}\n\n\tdirIndex := w.B\n\tlastModified := fileInfo.ModTime()\n\tff := &fsFile{","sourceCodeStart":1813,"sourceCodeEnd":1849,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1813-L1849","documentation":"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'.","triggerScenarios":"Enabling compression (Compress=true or per-encoding compressedFileSuffixes) on fsHandler and serving a file whose fs.File implementation is not an io.Seeker.","commonSituations":"Custom fs.File implementations wrapping streams (HTTP downloads, pipes) under a compressing static handler; memory-mapped or generated file substitutes lacking Seek.","solutions":["Make the returned fs.File implement io.Seeker (wrap with a seekable backing store)","Serve files backed by *os.File when compression is enabled","Disable Compress for handlers serving non-seekable sources","Compress content yourself out-of-band and serve the pre-compressed file with the expected compressed suffix"],"exampleFix":"// before\nreturn &streamFile{rc: resp.Body} // not a Seeker\n// after\nf, err := os.CreateTemp(\"\", \"dl-\")\nio.Copy(f, resp.Body)\nf.Seek(0, io.SeekStart)\nreturn f, nil","handlingStrategy":"type-guard","validationCode":"if _, ok := file.(io.Seeker); !ok {\n    // compression requires seekability; disable Compress or buffer the file\n}","typeGuard":"func compressible(f fs.File) bool {\n    _, ok := f.(io.Seeker)\n    return ok\n}","tryCatchPattern":"f, err := openCompressed(path)\nif err != nil && strings.Contains(err.Error(), \"seek is not implemented\") {\n    // serve uncompressed via plain handler\n}","preventionTips":["Only enable Compress on handlers serving real files","Wrap streams into temp files before compressed serving","Keep fasthttp versions current; compression paths evolve","Test compression with every custom fs.File implementation"],"tags":["go","fasthttp","compression","io-seeker"],"backgroundTag":"io-seeker-not-implemented","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}