nats-io/nats-server · error

smb.truncate: %w

Error message

smb.truncate: %w

What it means

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.

Source

Thrown at server/filestore.go:11371

				fs.mu.Unlock()
				return err
			}
			goto SKIP
		}

		// Make sure writeable.
		if err := smb.enableForWriting(fs.fip); err != nil {
			smb.mu.Unlock()
			fs.mu.Unlock()
			return err
		}

		// Truncate our selected message block.
		nmsgs, nbytes, err := smb.truncate(lsm.seq, lsm.ts)
		if err != nil {
			smb.mu.Unlock()
			fs.mu.Unlock()
			return fmt.Errorf("smb.truncate: %w", err)
		}
		// Account for the truncated msgs and bytes.
		purged += nmsgs
		bytes += nbytes

		// The selected message block is not the last anymore, need to close down resources.
		if hasWrittenTombstones {
			// Quit our loops.
			if smb.qch != nil {
				close(smb.qch)
				smb.qch = nil
			}
			smb.closeFDsLockedNoCheck()
			smb.recompressOnDiskIfNeeded()
		}
		smb.mu.Unlock()
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Check the wrapped cause (%w) — fix the underlying I/O issue (disk full, permissions, read-only mount).
  2. Retry the purge after resolving storage issues; ensure free disk space and correct ownership of the stream directory.
  3. If a specific message block is corrupted, remove/rebuild the stream or restore from backup.
  4. Check the NATS server log for preceding filestore errors identifying the failing block file.
Defensive patterns

Strategy: retry

Validate before calling

// before purging, ensure the store dir is writable and has space
var st syscall.Statfs_t
syscall.Statfs(storeDir, &st)
if st.Bavail*uint64(st.Bsize) < minFreeBytes { return errors.New("insufficient disk space") }

Try / catch

// Go: unwrap and classify with errors.Unwrap / errors.Is
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) { /* retry after fixing disk */ }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/96b7d83e02f8b7f3. Report an issue: GitHub.