{"record":{"id":"fb67beeccc406cc7","repo":"valyala/fasthttp","slug":"cannot-move-compressed-file-from-q-to-q-w","errorCode":null,"errorMessage":"cannot move compressed file from %q to %q: %w","messagePattern":"cannot move compressed file from %q to %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":1788,"sourceCode":"\t\tif errf := zw.Flush(); err == nil {\n\t\t\terr = errf\n\t\t}\n\t\treleaseStacklessZstdWriter(zw, CompressZstdDefault)\n\t}\n\t_ = zf.Close()\n\t_ = f.Close()\n\tif err != nil {\n\t\t_ = os.Remove(tmpFilePath)\n\t\treturn nil, fmt.Errorf(\"error when compressing file %q to %q: %w\", filePath, tmpFilePath, err)\n\t}\n\tif err = os.Chtimes(tmpFilePath, time.Now(), fileInfo.ModTime()); err != nil {\n\t\t_ = os.Remove(tmpFilePath)\n\t\treturn nil, fmt.Errorf(\"cannot change modification time to %v for tmp file %q: %v\",\n\t\t\tfileInfo.ModTime(), tmpFilePath, err)\n\t}\n\tif err = os.Rename(tmpFilePath, compressedFilePath); err != nil {\n\t\t_ = os.Remove(tmpFilePath)\n\t\treturn nil, fmt.Errorf(\"cannot move compressed file from %q to %q: %w\", tmpFilePath, compressedFilePath, err)\n\t}\n\treturn h.newCompressedFSFile(compressedFilePath, fileEncoding)\n}\n\n// newCompressedFSFileCache use memory cache compressed files.\nfunc (h *fsHandler) newCompressedFSFileCache(f fs.File, fileInfo fs.FileInfo, filePath, fileEncoding string) (*fsFile, error) {\n\tvar (\n\t\tw   = &bytebufferpool.ByteBuffer{}\n\t\terr error\n\t)\n\n\tswitch fileEncoding {\n\tcase \"br\":\n\t\tzw := acquireStacklessBrotliWriter(w, CompressDefaultCompression)\n\t\t_, err = copyZeroAlloc(zw, f)\n\t\tif errf := zw.Flush(); err == nil {\n\t\t\terr = errf\n\t\t}","sourceCodeStart":1770,"sourceCodeEnd":1806,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1770-L1806","documentation":"After compression and timestamp fix-up succeed, fasthttp atomically moves the temp file into its final compressed-cache location with os.Rename. If the rename fails, the temp file is removed and this error wraps the cause, naming source (temp) and destination paths. Common causes are cross-device renames or a missing/conflicting destination directory.","triggerScenarios":"The directory of the compressed cache path was removed between CreateTemp and Rename; the temp dir and target dir reside on different filesystems (Rename cannot cross devices); another process holds the target path in a way that makes rename fail (rare on POSIX).","commonSituations":"CachePath pointing to a different mounted volume than the temp file location; cache dir deleted by cleanup while under load; permission loss on the destination directory mid-run.","solutions":["Ensure the compressed-file directory exists, is writable, and lives on the same filesystem as its temp files (don't split cache across mounts).","Check the wrapped cause: EXDEV means cross-device rename — align temp and cache locations.","Stop external cleaners from deleting the cache directory while the server runs.","Retry the request; the temp file is cleaned up so the next attempt starts fresh."],"exampleFix":"// before: cache on another mount -> EXDEV\nfs := &fasthttp.FS{Root: \"/srv/www\", Compress: true} // tmp in /srv/www, cache target on /mnt/cache\n// after: keep cache alongside source files (same fs)\nfs := &fasthttp.FS{Root: \"/srv/www\", Compress: true, CompressedFileSuffix: \".gz\"}","handlingStrategy":"retry","validationCode":"if fi, err := os.Stat(filepath.Dir(compressedPath)); err != nil || !fi.IsDir() {\n    os.MkdirAll(filepath.Dir(compressedPath), 0o755)\n}\n// ensure same device: compare syscall.Stat_t.Dev of temp dir and target dir","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"cannot move compressed file\") {\n    // EXDEV => reconfigure cache to same filesystem; otherwise retry\n}","preventionTips":["Keep temp files and final cache files on the same filesystem (avoid EXDEV).","Don't delete the cache directory while the server is running.","Ensure the destination directory stays writable for the service user."],"tags":["filesystem","fasthttp","compression","rename","cache"],"backgroundTag":"file-rename-failed","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}