nats-io/nats-server · error

error purging stream: %w

Error message

error purging stream: %w

What it means

After the stream is created in restore mode, the store is compacted to nstate.FirstSeq so the restored messages start at the correct sequence (essential when the backup is empty or restores to no interest). If store.Compact fails, the restore aborts with this wrapped storage error.

Source

Thrown at server/stream_backup.go:391

	}
	defer func() {
		var state StreamState
		mset.store.FastState(&state)
		mset.mu.Lock()
		mset.lseq = state.LastSeq
		mset.mu.Unlock()
		if err := mset.completeRestore(); err != nil {
			if err = fmt.Errorf("failed to activate stream %q: %w", cfg.Name, err); retErr == nil {
				retErr = err
			}
			s.Warnf("JetStream stream restore for '%s > %s' failed to activate stream: %v", a.Name, cfg.Name, err)
		}
	}()

	// Start off at the right sequence number. This is important in particular
	// when the backup contains no messages or would restore to no interest.
	if _, err = mset.store.Compact(nstate.FirstSeq); err != nil {
		return nil, fmt.Errorf("error purging stream: %w", err)
	}

	var restoredConsumers, ephemerals []*consumer
	defer func() {
		// Consumers must be unconditionally converted and completed, otherwise
		// a partial restore that fails midway through can leave assets that are
		// unusable.
		for _, o := range ephemerals {
			o.switchToEphemeral()
		}
		for _, o := range restoredConsumers {
			if err := o.completeRestore(); err != nil {
				if err = fmt.Errorf("failed to activate consumer %q: %w", o.name, err); retErr == nil {
					retErr = err
				}
				s.Warnf("JetStream stream restore for '%s > %s' failed to activate consumers: %v", a.Name, cfg.Name, err)
			}
		}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Check the store's underlying cause in logs: free disk space, fix permissions, or replace failing storage
  2. Verify state.json's FirstSeq is a sane value from the original backup; regenerate the snapshot if it was hand-edited
  3. For MemoryStorage streams, ensure the server has adequate memory for the stream
  4. Delete any partial stream left behind and retry the restore once storage is healthy
Defensive patterns

Strategy: try-catch

Validate before calling

if freeDisk(storeDir) < nstate.Bytes || isReadOnly(storeDir) {
    return fmt.Errorf("store not ready for restore compaction")
}

Try / catch

mset, err := acc.RestoreStreamV2(cfg, r)
if err != nil {
    if strings.Contains(err.Error(), "error purging stream") {
        // inspect store health (disk space, perms) before retrying
    }
    return err
}

Prevention

When it happens

Trigger: mset.store.Compact(nstate.FirstSeq) returns an error: the storage engine (file/memory) fails to truncate the stream to the snapshot's FirstSeq — usually disk I/O errors, out-of-space conditions, or a corrupted freshly-created store; a malformed snapshot with an invalid FirstSeq can also drive edge-case store behavior.

Common situations: Filesystem full or read-only during a restore to a FileStorage stream; restoring onto a volume with failing disks; snapshot state.json with FirstSeq values inconsistent with the target store; very large Compact operations hitting memory limits in MemoryStorage.

Related errors


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