dgraph-io/badger · error
Index Cache must be set for encrypted workloads
Error message
Index Cache must be set for encrypted workloads
What it means
For encrypted workloads the table index cannot be kept as plain bytes in memory; it must be cached decrypted. fetchIndex panics when the table requires decryption but opt.IndexCache is nil, because there would be nowhere to store the decrypted index.
Source
Thrown at table/table.go:533
for i := 0; i < oLen; i += jump {
if i >= oLen {
i = oLen - 1
}
y.AssertTrue(t.offsets(&bo, i))
if bytes.HasPrefix(bo.KeyBytes(), prefix) {
res = append(res, string(bo.KeyBytes()))
}
}
return res
}
func (t *Table) fetchIndex() *fb.TableIndex {
if !t.shouldDecrypt() {
return t._index
}
if t.opt.IndexCache == nil {
panic("Index Cache must be set for encrypted workloads")
}
if val, ok := t.opt.IndexCache.Get(t.indexKey()); ok && val != nil {
return val
}
index, err := t.readTableIndex()
y.Check(err)
t.opt.IndexCache.Set(t.indexKey(), index, int64(t.indexLen))
return index
}
func (t *Table) offsets(ko *fb.BlockOffset, i int) bool {
return t.fetchIndex().Offsets(ko, i)
}
// block function return a new block. Each block holds a ref and the byte
// slice stored in the block will be reused when the ref becomes zero. The
// caller should release the block by calling block.decrRef() on it.View on GitHub (pinned to 2a001d466f)
Solutions
- Set WithIndexCache (e.g. ristretto.NewCache) in the options when encryption is enabled
- Re-open the DB with both WithEncryptionKey and a non-nil IndexCache
- If encryption is unintended, remove WithEncryptionKey so fetchIndex returns the plain index
Example fix
// before
opt := badger.DefaultOptions(dir).
WithEncryptionKey(key)
// after
ic, _ := ristretto.NewCache(&ristretto.Config{NumCounters: 1e6, MaxCost: 1 << 30})
opt := badger.DefaultOptions(dir).
WithEncryptionKey(key).
WithIndexCache(ic) Defensive patterns
Strategy: validation
Validate before calling
if opt.EncryptionKey != nil && opt.IndexCache == nil {
ic, err := ristretto.NewCache(&ristretto.Config{
NumCounters: 1e6, MaxCost: 1 << 30, BufferItems: 64,
})
if err != nil { return err }
opt.IndexCache = ic
} Try / catch
func safeOpen(opt badger.Options) (*badger.DB, error) {
if opt.EncryptionKey != nil && opt.IndexCache == nil {
return nil, errors.New("encryption requires WithIndexCache")
}
return badger.Open(opt)
} Prevention
- Always pair WithEncryptionKey with WithIndexCache in your options builder
- Centralize option construction in one factory function
- Add a startup assertion/test for encrypted deployments
When it happens
Trigger: Opening a DB with WithEncryptionKey set but without WithIndexCache, then calling any API that reads the index: t.offsets(), StaleDataSize(), DoesNotHave(), VerifyChecksum(), or normal iteration on an encrypted table.
Common situations: Users enabling Badger's encryption feature but forgetting the mandatory IndexCache option; copying options from a non-encrypted setup to an encrypted one.
Related errors
- BlockCacheSize should be set since compression/encryption ar
- ErrValueLogSize
- ErrThresholdZero
- ErrNamespaceMode
- ErrZeroBandwidth
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/d1b715b2863f5b6f.
Report an issue: GitHub.