nats-io/nats-server · error
failed to close temporary file: %w
Error message
failed to close temporary file: %w
What it means
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.
Source
Thrown at server/filestore.go:8070
}
// Re-encrypt the block if necessary.
if err = mb.encryptOrDecryptIfNeeded(buf); err != nil {
return errorCleanup(err)
}
// Write the new block data (which might be compressed or encrypted) to the
// temporary file.
if n, err := tmpFD.Write(buf); err != nil {
return errorCleanup(fmt.Errorf("failed to write to temporary file: %w", err))
} else if n != len(buf) {
return errorCleanup(fmt.Errorf("short write to temporary file (%d != %d)", n, len(buf)))
}
if err := tmpFD.Sync(); err != nil {
return errorCleanup(fmt.Errorf("failed to sync temporary file: %w", err))
}
if err := tmpFD.Close(); err != nil {
return errorCleanup(fmt.Errorf("failed to close temporary file: %w", err))
}
// Now replace the original file with the newly updated temp file.
if err := os.Rename(tmpFN, origFN); err != nil {
return fmt.Errorf("failed to move temporary file into place: %w", err)
}
// Since the message block might be retained in memory, make sure the
// compression algorithm is up-to-date, since this will be needed when
// compacting or truncating.
mb.cmp = alg
// Also update rbytes
mb.rbytes = uint64(len(buf))
return nil
}
View on GitHub (pinned to 3a66a489d2)
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.
Example fix
// before: default low limit // after: raise fd limit (systemd) // LimitNOFILE=1048576
Defensive patterns
Strategy: validation
Validate before calling
// check fd headroom before high-throughput writes
if fds, err := countOpenFDs(pid); err == nil && float64(fds)/float64(fdLimit) > 0.8 {
// raise LimitNOFILE or reduce concurrent streams
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to close temporary file") {
// usually fd exhaustion or deferred I/O error; check ulimit and disk
} Prevention
- 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.
When it happens
Trigger: tmpFD.Close() returns an error after a successful write and Sync of new block data during a message block update.
Common situations: File descriptor exhaustion (too many open files), filesystem state issues after earlier I/O errors, or storage driver problems on virtualized/containerized filesystems.
Related errors
- failed to write to temporary file: %w
- short write to temporary file (%d != %d)
- failed to sync temporary file: %w
- failed to move temporary file into place: %w
- fileStore requires file storage type in config
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/1c821dc9bafa2f93.
Report an issue: GitHub.