{"record":{"id":"a217caf3f1c130a4","repo":"nats-io/nats-server","slug":"short-write-to-temporary-file-d-d","errorCode":null,"errorMessage":"short write to temporary file (%d != %d)","messagePattern":"short write to temporary file \\((.+?) != (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/filestore.go","lineNumber":8064,"sourceCode":"\t\t// writing metadata.\n\t\tmeta := &CompressionInfo{\n\t\t\tAlgorithm:    alg,\n\t\t\tOriginalSize: uint64(originalSize),\n\t\t}\n\t\tbuf = append(meta.MarshalMetadata(), buf...)\n\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","sourceCodeStart":8046,"sourceCodeEnd":8082,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L8046-L8082","documentation":"Returned when a write to the temporary block file completed without error but wrote fewer bytes than the buffer length (short write). The file store treats this as a failed update and aborts via errorCleanup, leaving the original block file intact.","triggerScenarios":"tmpFD.Write(buf) returns n != len(buf) during a file-store message block update — a partial write of the compressed/encrypted block buffer.","commonSituations":"Underlying storage returning partial writes (NFS/CIFS mounts, iSCSI issues), disk quotas silently truncating writes, or extremely large block buffers on unreliable storage.","solutions":["Move the JetStream store onto a reliable local filesystem (ext4/xfs), not network mounts.","Check disk quotas (quota -s) on the storage volume.","Inspect storage subsystem logs for partial-write/IO errors.","Retry the operation; the temp file is cleaned up automatically."],"exampleFix":"// before: store on NFS mount\nStoreDir: /mnt/nfs/jetstream\n// after: local disk\nStoreDir: /var/lib/nats/jetstream","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"short write to temporary file\") {\n    // treat storage as unreliable; migrate store to local disk, alert ops\n}","preventionTips":["Run JetStream on local ext4/xfs, never NFS/SMB/CIFS.","Check disk quotas on the storage volume.","Validate storage reliability under load before production.","Monitor partial-write and storage errors in dmesg/syslog."],"tags":["filestore","filesystem","io","jetstream","go"],"backgroundTag":"short-write","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}