nats-io/nats-server · error
ErrSetNotEmpty
ErrSetNotEmpty
Error message
ss: set not empty
What it means
ErrSetNotEmpty is returned by SequenceSet.SetInitialMin when the set already contains values. SetInitialMin can only initialize a fresh, empty set with a starting minimum, so calling it on a populated set is rejected to avoid corrupting existing intervals.
Source
Thrown at server/avl/seqset.go:309
i += 8
ss.root.nodeIter(func(n *node) {
le.PutUint64(buf[i:], n.base)
i += 8
for _, b := range n.bits {
le.PutUint64(buf[i:], b)
i += 8
}
le.PutUint16(buf[i:], uint16(n.h))
i += 2
})
return buf[:i]
}
// ErrBadEncoding is returned when we can not decode properly.
var (
ErrBadEncoding = errors.New("ss: bad encoding")
ErrBadVersion = errors.New("ss: bad version")
ErrSetNotEmpty = errors.New("ss: set not empty")
)
// Decode returns the sequence set and number of bytes read from the buffer on success.
func Decode(buf []byte) (*SequenceSet, int, error) {
if len(buf) < minLen || buf[0] != magic {
return nil, -1, ErrBadEncoding
}
switch v := buf[1]; v {
case 1:
return decodev1(buf)
case 2:
return decodev2(buf)
default:
return nil, -1, ErrBadVersion
}
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Only call SetInitialMin right after creating the SequenceSet, before any adds or Decode
- Check ss.IsEmpty() before calling SetInitialMin and skip if already populated
- If you need to seed a minimum on a populated set, delete the set and rebuild it with the desired initial value
Example fix
// before
ss.SetInitialMin(min) // panics-free but errors if ss already restored
// after
if ss.IsEmpty() {
ss.SetInitialMin(min)
} Defensive patterns
Strategy: validation
Validate before calling
if !ss.IsEmpty() {
// already initialized; skip seeding
} else {
ss.SetInitialMin(min)
} Try / catch
err := ss.SetInitialMin(min)
if errors.Is(err, avl.ErrSetNotEmpty) {
log.Debug("sequence set already populated; skipping initial min")
} Prevention
- Call SetInitialMin only immediately after constructing the SequenceSet
- Guard with IsEmpty() before seeding
- Avoid re-running init logic on restored state
When it happens
Trigger: Calling SetInitialMin on a SequenceSet that already has entries (e.g. one loaded via Decode or previously added to).
Common situations: Reinitializing a consumer's pending/reserved sequence state that was already restored from disk, or double-initialization during setup code.
Related errors
- ErrBadEncoding
- fileStore requires file storage type in config
- filestore max block size is %s
- could not create storage directory - %v
- storage directory is not a directory
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/a1d47d93480eb2e4.
Report an issue: GitHub.