{"record":{"id":"96b7d83e02f8b7f3","repo":"nats-io/nats-server","slug":"smb-truncate-w","errorCode":null,"errorMessage":"smb.truncate: %w","messagePattern":"smb\\.truncate: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/filestore.go","lineNumber":11371,"sourceCode":"\t\t\t\tfs.mu.Unlock()\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tgoto SKIP\n\t\t}\n\n\t\t// Make sure writeable.\n\t\tif err := smb.enableForWriting(fs.fip); err != nil {\n\t\t\tsmb.mu.Unlock()\n\t\t\tfs.mu.Unlock()\n\t\t\treturn err\n\t\t}\n\n\t\t// Truncate our selected message block.\n\t\tnmsgs, nbytes, err := smb.truncate(lsm.seq, lsm.ts)\n\t\tif err != nil {\n\t\t\tsmb.mu.Unlock()\n\t\t\tfs.mu.Unlock()\n\t\t\treturn fmt.Errorf(\"smb.truncate: %w\", err)\n\t\t}\n\t\t// Account for the truncated msgs and bytes.\n\t\tpurged += nmsgs\n\t\tbytes += nbytes\n\n\t\t// The selected message block is not the last anymore, need to close down resources.\n\t\tif hasWrittenTombstones {\n\t\t\t// Quit our loops.\n\t\t\tif smb.qch != nil {\n\t\t\t\tclose(smb.qch)\n\t\t\t\tsmb.qch = nil\n\t\t\t}\n\t\t\tsmb.closeFDsLockedNoCheck()\n\t\t\tsmb.recompressOnDiskIfNeeded()\n\t\t}\n\t\tsmb.mu.Unlock()\n\t}\n","sourceCodeStart":11353,"sourceCodeEnd":11389,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L11353-L11389","documentation":"Wraps an error returned by smb.truncate() when compacting a stream message block during a purge/compact operation. The message block could not be truncated to the given sequence/timestamp, so the compact aborts with locks released. This prevents partially truncated message blocks from being silently accepted.","triggerScenarios":"Calling Stream.Purge with a Keep/Since/sequence compact option that selects a message block, and smb.truncate(lsm.seq, lsm.ts) fails (e.g. underlying file write/truncate I/O error or internal state error).","commonSituations":"Running Stream Purge API with 'keep' or 'seq' filters on a file-backed stream while the disk is full, read-only, or the message block file is corrupted.","solutions":["Check the wrapped cause (%w) — fix the underlying I/O issue (disk full, permissions, read-only mount).","Retry the purge after resolving storage issues; ensure free disk space and correct ownership of the stream directory.","If a specific message block is corrupted, remove/rebuild the stream or restore from backup.","Check the NATS server log for preceding filestore errors identifying the failing block file."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before purging, ensure the store dir is writable and has space\nvar st syscall.Statfs_t\nsyscall.Statfs(storeDir, &st)\nif st.Bavail*uint64(st.Bsize) < minFreeBytes { return errors.New(\"insufficient disk space\") }","typeGuard":null,"tryCatchPattern":"// Go: unwrap and classify with errors.Unwrap / errors.Is\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) { /* retry after fixing disk */ }\n}","preventionTips":["Monitor disk free space and inode usage","Purge during low-traffic windows","Watch nats-server logs for filestore I/O errors","Keep stream directories on healthy, writable volumes"],"tags":["jetstream","filestore","purge","truncate","io"],"backgroundTag":"filestore-truncate-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}