{"record":{"id":"5b6b06f361ac5b01","repo":"valyala/fasthttp","slug":"cannot-obtain-info-for-compressed-file-q-w","errorCode":null,"errorMessage":"cannot obtain info for compressed file %q: %w","messagePattern":"cannot obtain info for compressed file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":1872,"sourceCode":"\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)\n\t\t}\n\n\t\t// If the file is not found and the path is empty, let's return errDirIndexRequired error.\n\t\tif filePath == \"\" && (errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrInvalid)) {\n\t\t\treturn nil, errDirIndexRequired","sourceCodeStart":1854,"sourceCodeEnd":1890,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1854-L1890","documentation":"Companion to [110]: after successfully opening a compressed cache file, fasthttp calls Stat to obtain its metadata (size, modtime) required to build the *fsFile. If Stat fails, the file is closed and this error wraps the cause. It indicates the cache file's metadata became unavailable right after a successful open.","triggerScenarios":"Stat failing on an already-open compressed cache file — concurrent deletion between Open and Stat (racing cleaner/deploy), permission change on the parent directory, or network filesystem errors (ESTALE) after open.","commonSituations":"Cache cleanup daemon removing .fasthttp.* files mid-request; NFS stale handles; containers where the static volume is unmounted/re-mounted during runtime.","solutions":["Retry the request: fasthttp will re-open/re-compress; the race is usually transient.","Stop concurrent deletion of compressed cache files (coordinate cleaners with deploys, use atomic renames).","Check the wrapped cause: ESTALE/ENOENT points to NFS or removal races — move cache to local disk.","Verify directory permissions on the static root haven't changed for the service user."],"exampleFix":"// before: cron deleting cache while serving\n// */5 * * * * find /srv/www -name '*.fasthttp.*' -delete\n// after: remove the racy cleanup; let fasthttp manage/regenerate cache\nfs := &fasthttp.FS{Root: \"/srv/www\", Compress: true}","handlingStrategy":"retry","validationCode":"if fi, err := os.Stat(compressedPath); err != nil || fi.IsDir() {\n    // cache file unavailable; skip or regenerate before serving\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"cannot obtain info for compressed file\") {\n    // transient race; retry the request, fasthttp will rebuild the cache entry\n}","preventionTips":["Never delete compressed cache files concurrently with serving.","Verify directory permissions remain stable for the service user.","Avoid NFS for cache dirs; stale handles break open-then-stat sequences."],"tags":["fasthttp","filesystem","stat","compression-cache","race-condition"],"backgroundTag":"file-stat-failed","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}