{"record":{"id":"ce9ae38b8fb6d71c","repo":"nats-io/nats-server","slug":"failed-to-move-temporary-file-into-place-w","errorCode":null,"errorMessage":"failed to move temporary file into place: %w","messagePattern":"failed to move temporary file into place: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/filestore.go","lineNumber":8075,"sourceCode":"\t}\n\n\t// Write the new block data (which might be compressed or encrypted) to the\n\t// temporary file.\n\tif n, err := tmpFD.Write(buf); err != nil {\n\t\treturn errorCleanup(fmt.Errorf(\"failed to write to temporary file: %w\", err))\n\t} else if n != len(buf) {\n\t\treturn errorCleanup(fmt.Errorf(\"short write to temporary file (%d != %d)\", n, len(buf)))\n\t}\n\tif err := tmpFD.Sync(); err != nil {\n\t\treturn errorCleanup(fmt.Errorf(\"failed to sync temporary file: %w\", err))\n\t}\n\tif err := tmpFD.Close(); err != nil {\n\t\treturn errorCleanup(fmt.Errorf(\"failed to close temporary file: %w\", err))\n\t}\n\n\t// Now replace the original file with the newly updated temp file.\n\tif err := os.Rename(tmpFN, origFN); err != nil {\n\t\treturn fmt.Errorf(\"failed to move temporary file into place: %w\", err)\n\t}\n\n\t// Since the message block might be retained in memory, make sure the\n\t// compression algorithm is up-to-date, since this will be needed when\n\t// compacting or truncating.\n\tmb.cmp = alg\n\n\t// Also update rbytes\n\tmb.rbytes = uint64(len(buf))\n\n\treturn nil\n}\n\n// Lock should be held.\nfunc (mb *msgBlock) decompressIfNeeded(buf []byte) ([]byte, error) {\n\tvar meta CompressionInfo\n\tif n, err := meta.UnmarshalMetadata(buf); err != nil {\n\t\t// There was a problem parsing the metadata header of the block.","sourceCodeStart":8057,"sourceCodeEnd":8093,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L8057-L8093","documentation":"Returned when os.Rename(tmpFN, origFN) fails while swapping the updated temporary block file into place after a successful write/sync/close. The new block data is fully written but could not atomically replace the original file, so the update fails with this wrapped error.","triggerScenarios":"os.Rename fails during the final commit step of a message block update — replacing the original block file with the temp file.","commonSituations":"Temp file and target on different filesystems (store dir partially relocated or symlinked), missing write permission on the directory (rename requires dir write), the original file removed/locked by backup agents, or cross-device link (EXDEV) errors in container volume setups.","solutions":["Ensure the entire JetStream store directory is on the same filesystem (no split symlinks/bind mounts).","Verify write permission on the stream's data directory for the nats process user.","Stop backup/AV agents from holding or removing files under the store directory mid-update.","Retry the update once the directory state is fixed; the temp file may need manual removal if errorCleanup missed it."],"exampleFix":"// before: split filesystems\nStoreDir: /data/jetstream  # with symlink to /mnt/other/blockdir\n// after: single filesystem\nStoreDir: /data/jetstream  # entire tree on one volume","handlingStrategy":"validation","validationCode":"// ensure store dir is one filesystem and writable before starting\ninfo1, _ := os.Stat(storeDir)\ndev := info1.Sys().(*syscall.Stat_t).Dev\nif symlinkedAcrossDevices(storeDir) {\n    return fmt.Errorf(\"store dir spans multiple filesystems\")\n}\nif !writable(storeDir) {\n    return fmt.Errorf(\"no write permission on %s\", storeDir)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to move temporary file into place\") {\n    // check for EXDEV / permission issues; may need to remove leftover temp files\n}","preventionTips":["Keep the entire JetStream store tree on a single filesystem; avoid split symlinks/bind mounts.","Ensure the nats user owns the store directory with write permission.","Exclude the store directory from backup/AV scanning that locks files.","Clean leftover *.tmp files after failures."],"tags":["filestore","filesystem","rename","jetstream","go"],"backgroundTag":"rename-failed-exdev","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}