{"record":{"id":"1c821dc9bafa2f93","repo":"nats-io/nats-server","slug":"failed-to-close-temporary-file-w","errorCode":null,"errorMessage":"failed to close temporary file: %w","messagePattern":"failed to close temporary file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/filestore.go","lineNumber":8070,"sourceCode":"\t}\n\n\t// Re-encrypt the block if necessary.\n\tif err = mb.encryptOrDecryptIfNeeded(buf); err != nil {\n\t\treturn errorCleanup(err)\n\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","sourceCodeStart":8052,"sourceCodeEnd":8088,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L8052-L8088","documentation":"Returned when closing the temporary block file fails at the end of a file-store block update. Data was written and synced, but Close returned an error (often masking deferred flush issues), so the update aborts via errorCleanup.","triggerScenarios":"tmpFD.Close() returns an error after a successful write and Sync of new block data during a message block update.","commonSituations":"File descriptor exhaustion (too many open files), filesystem state issues after earlier I/O errors, or storage driver problems on virtualized/containerized filesystems.","solutions":["Check open file descriptor limits (ulimit -n) and raise them if exhausted.","Look for earlier I/O errors on the volume; Close often surfaces deferred write failures.","Verify the container/host storage driver supports standard POSIX file semantics.","Retry the operation after resolving the resource issue."],"exampleFix":"// before: default low limit\n// after: raise fd limit (systemd)\n// LimitNOFILE=1048576","handlingStrategy":"validation","validationCode":"// check fd headroom before high-throughput writes\nif fds, err := countOpenFDs(pid); err == nil && float64(fds)/float64(fdLimit) > 0.8 {\n    // raise LimitNOFILE or reduce concurrent streams\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to close temporary file\") {\n    // usually fd exhaustion or deferred I/O error; check ulimit and disk\n}","preventionTips":["Raise open file descriptor limits (LimitNOFILE=1048576).","Watch for earlier write/sync errors that close() may surface.","Use POSIX-compliant storage in containers (avoid overlayfs quirks on data volumes).","Monitor fd usage of the nats-server process."],"tags":["filestore","filesystem","io","jetstream","go"],"backgroundTag":"file-close-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}