dgraph-io/badger · critical
Arena too small, toWrite:%d newTotal:%d limit:%d
Error message
Arena too small, toWrite:%d newTotal:%d limit:%d
What it means
The skiplist Arena is a fixed-size buffer; putNode reserves space for a new node via an atomic counter and asserts the total stays within the arena capacity. When the allocation would exceed the buffer, this assertion panics. In Badger this normally cannot happen because the memtable is rotated before the arena fills, so hitting it indicates the size accounting/rotation logic was bypassed.
Source
Thrown at skl/arena.go:54
out.n.Store(1)
return out
}
func (s *Arena) size() int64 {
return int64(s.n.Load())
}
// putNode allocates a node in the arena. The node is aligned on a pointer-sized
// boundary. The arena offset of the node is returned.
func (s *Arena) putNode(height int) uint32 {
// Compute the amount of the tower that will never be used, since the height
// is less than maxHeight.
unusedSize := (maxHeight - height) * offsetSize
// Pad the allocation with enough bytes to ensure pointer alignment.
l := uint32(MaxNodeSize - unusedSize + nodeAlign)
n := s.n.Add(l)
y.AssertTruef(int(n) <= len(s.buf),
"Arena too small, toWrite:%d newTotal:%d limit:%d",
l, n, len(s.buf))
// Return the aligned offset.
m := (n - l + uint32(nodeAlign)) & ^uint32(nodeAlign)
return m
}
// Put will *copy* val into arena. To make better use of this, reuse your input
// val buffer. Returns an offset into buf. User is responsible for remembering
// size of val. We could also store this size inside arena but the encoding and
// decoding will incur some overhead.
func (s *Arena) putVal(v y.ValueStruct) uint32 {
l := v.EncodedSize()
n := s.n.Add(l)
y.AssertTruef(int(n) <= len(s.buf),
"Arena too small, toWrite:%d newTotal:%d limit:%d",
l, n, len(s.buf))View on GitHub (pinned to 2a001d466f)
Solutions
- Ensure memtable rotation: use badger's MemTable/DB layer which calls arena.ShouldRotate/rotate before capacity is reached, rather than writing directly to a raw skl.Skiplist.
- If constructing a skiplist yourself, allocate the arena large enough for your workload (buf size >= total of MaxNodeSize per node + key/value bytes).
- Keep keys/values within limits (maxKeySize/MaxValueSize) so a single entry cannot exceed arena size.
- Check for regressions if you modified skl or levels.go rotation logic; restore upstream capacity checks.
Example fix
// before arena := skl.NewArena(1 << 10) // 1KB, too small for workload list := skl.NewSkiplist(arena) list.Put(bigKey, bigVal) // panics: Arena too small // after arena := skl.NewArena(64 << 20) list := skl.NewSkiplist(arena) list.Put(bigKey, bigVal)
Defensive patterns
Strategy: validation
Validate before calling
// before writing to a manually managed skiplist
if int(arena.Size())+skl.MaxNodeSize >= arena.Capacity() || arena.ShouldRotate() {
rotateMemtable()
} Try / catch
defer func() {
if r := recover(); r != nil {
if strings.Contains(fmt.Sprint(r), "Arena too small") {
log.Printf("skiplist arena exhausted: %v", r)
}
panic(r)
}
}() Prevention
- Rely on badger's memtable rotation; don't write to a raw skl.Skiplist past capacity
- Size arenas generously for embedded use
- Keep entries within MaxKeySize/MaxValueSize
When it happens
Trigger: Inserting a node (via skl.Skiplist.newNode, driven by memtable Put) whose required size (key + value + maxHeight offsets) pushes the arena offset past len(s.buf) — i.e. writes continued after the arena's capacity was reached without rotating the memtable.
Common situations: Custom code constructing skl.Skiplist directly with a manually allocated arena that is too small; modifications to memtable rotation thresholds; embedded use of the skiplist package outside badger's memtable management.
Related errors
- Equality can happen only on base level: %d
- Cannot use NewTransactionAt with managedDB=false. Use NewTra
- cannot use NewWriteBatchAt with managedDB=false. Use NewWrit
- cannot use NewManagedWriteBatch with managedDB=false. Use Ne
- Cannot use CommitAt with managedDB=false. Use Commit instead
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/57d0743fa3fbee69.
Report an issue: GitHub.