nats-io/nats-server · critical
failed to write to temporary file: %w
Error message
failed to write to temporary file: %w
What it means
Returned when the file store fails to write the (possibly compressed/encrypted) block buffer to the temporary file during a block update. The write to tmpFD returned an OS-level error, so the update is aborted via errorCleanup. The original file remains untouched.
Source
Thrown at server/filestore.go:8062
// We only need to write out the metadata header if compression is enabled.
// If we're trying to uncompress the file on disk at this point, don't bother
// writing metadata.
meta := &CompressionInfo{
Algorithm: alg,
OriginalSize: uint64(originalSize),
}
buf = append(meta.MarshalMetadata(), buf...)
}
// 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.View on GitHub (pinned to 3a66a489d2)
Solutions
- Check free disk space on the stream's storage directory (df -h).
- Check filesystem health and mount status; dmesg for I/O errors.
- Verify permissions on the store directory and that no ulimit (nofile) is exhausted.
- Retry the publish/update once space is freed; errorCleanup removed the temp file so no manual cleanup is needed.
Example fix
// before: publish while disk is 100% full nc.Publish(subj, payload) // after: ensure capacity before writing, or monitor // df -h /path/to/jetstream ; free space or relocate store dir
Defensive patterns
Strategy: validation
Validate before calling
// before writing, check available space on the store volume
usage := diskUsage(storeDir)
if usage.Free < requiredBytes {
return fmt.Errorf("insufficient disk space: %d free", usage.Free)
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to write to temporary file") {
// alert ops: check disk space / I/O on store volume
} Prevention
- Alert on disk usage thresholds (e.g. 80%) for the JetStream store volume.
- Use reliable local storage, not network filesystems.
- Monitor fd limits and directory permissions.
- Set up log monitoring for ENOSPC and I/O errors.
When it happens
Trigger: tmpFD.Write(buf) returns a non-nil error while writing new block data to the temp file during a message block update (writeMsgs/update of a file-store stream).
Common situations: Disk full (ENOSPC), I/O errors on failing disks, temp directory on a full/unmounted filesystem, file descriptor limits hit, or permissions changed on the stream's data directory.
Related errors
- short write to temporary file (%d != %d)
- failed to close temporary file: %w
- 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/e11520d8395bd5a3.
Report an issue: GitHub.