{"record":{"id":"5a9d68f187f766ea","repo":"valyala/fasthttp","slug":"cannot-open-compressed-file-q-w","errorCode":null,"errorMessage":"cannot open compressed file %q: %w","messagePattern":"cannot open compressed file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":1867,"sourceCode":"\tff := &fsFile{\n\t\th:               h,\n\t\tdirIndex:        dirIndex,\n\t\tcontentType:     contentType,\n\t\tcontentLength:   len(dirIndex),\n\t\tcompressed:      true,\n\t\tlastModified:    lastModified,\n\t\tlastModifiedStr: AppendHTTPDate(nil, lastModified),\n\n\t\tt: time.Now(),\n\t}\n\n\treturn ff, nil\n}\n\nfunc (h *fsHandler) newCompressedFSFile(filePath, fileEncoding string) (*fsFile, error) {\n\tf, err := h.filesystem.Open(filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot open compressed file %q: %w\", filePath, err)\n\t}\n\tfileInfo, err := f.Stat()\n\tif err != nil {\n\t\t_ = f.Close()\n\t\treturn nil, fmt.Errorf(\"cannot obtain info for compressed file %q: %w\", filePath, err)\n\t}\n\treturn h.newFSFile(f, fileInfo, true, filePath, fileEncoding)\n}\n\nfunc (h *fsHandler) openFSFile(filePath string, mustCompress bool, fileEncoding string) (*fsFile, error) {\n\tfilePathOriginal := filePath\n\tif mustCompress {\n\t\tfilePath += h.compressedFileSuffixes[fileEncoding]\n\t}\n\tf, err := h.filesystem.Open(filePath)\n\tif err != nil {\n\t\tif mustCompress && errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn h.compressAndOpenFSFile(filePathOriginal, fileEncoding)","sourceCodeStart":1849,"sourceCodeEnd":1885,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1849-L1885","documentation":"newCompressedFSFile opens an existing compressed cache file (original path + compressed suffix) to serve it from disk cache. If the filesystem Open fails, this error wraps the cause. This typically happens when the compressed file disappeared between the existence check and the open, or it was never readable.","triggerScenarios":"A request hits the serve-from-compressed-cache path where the .fasthttp.* cache file was deleted by a concurrent cleanup or overwritten deploy between lookup and Open; or the compressed file exists but the process lost read permission.","commonSituations":"Deploy scripts rsyncing static roots with --delete while the server runs; external cache cleaners; permission changes after rotating service users; NFS 'stale file handle' on the cache file.","solutions":["Check the wrapped cause: fs.ErrNotExist means the cache file vanished — retry the request so fasthttp recompresses it.","Exclude fasthttp cache files (CompressedFileSuffix pattern) from deploy rsync --delete and cleanup jobs.","Ensure the service user can read the static root and cache files.","If on NFS, remount or move the static root to local disk to avoid stale handles."],"exampleFix":"// before: rsync --delete purges .fasthttp.gz cache during deploys\n// rsync -a --delete ./dist/ /srv/www/\n// after: keep cache files\n// rsync -a --delete --exclude='*.fasthttp.*' ./dist/ /srv/www/","handlingStrategy":"retry","validationCode":"compressedPath := path + \".fasthttp.\" + ext\nif _, err := os.Stat(compressedPath); err != nil {\n    // cache missing: either pre-generate or accept regeneration on retry\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"cannot open compressed file\") && errors.Is(err, fs.ErrNotExist) {\n    // retry once: fasthttp will recreate the cache file\n}","preventionTips":["Exclude compressed cache files from rsync --delete and cleanup jobs.","Coordinate deploys with cache lifecycle; prefer atomic directory swaps.","Keep static roots on stable local storage rather than NFS."],"tags":["fasthttp","filesystem","compression-cache","file-open"],"backgroundTag":"compressed-cache-file-missing","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}