gofiber/fiber · error
cache: failed to delete key %q while evicting: %w
Error message
cache: failed to delete key %q while evicting: %w
What it means
The compound failure during eviction rollback: deleteKey of an evicted key failed (delErr) AND the subsequent attempt to restore the displaced entry's heap index (refreshHeapIndex) also failed (restoreErr). Fiber returns errors.Join of both wrapped errors so callers see the eviction delete failure and the index-restore failure. This is the worst-case eviction path — both the delete and the compensating write broke.
Source
Thrown at middleware/cache/cache.go:681
// Re-add entries to the heap to keep expiration tracking consistent
var restored []evictionCandidate
for j := i; j < len(candidates); j++ {
candidate := candidates[j]
candidate.heapIdx = heap.put(candidate.key, candidate.exp, candidate.size)
restored = append(restored, candidate)
}
mux.Unlock()
var restoreErr error
for _, candidate := range restored {
if err := refreshHeapIndex(reqCtx, candidate); err != nil {
restoreErr = errors.Join(restoreErr, err)
}
}
if restoreErr != nil {
return errors.Join(fmt.Errorf("cache: failed to delete key %q while evicting: %w", maskKey(keyToRemove), delErr), restoreErr)
}
return fmt.Errorf("cache: failed to delete key %q while evicting: %w", maskKey(keyToRemove), delErr)
}
}
}
e = manager.acquire()
// Cache response
e.body = utils.CopyBytes(c.Response().Body())
e.status = c.Response().StatusCode()
e.ctype = utils.CopyBytes(c.Response().Header.ContentType())
e.cencoding = utils.CopyBytes(c.Response().Header.Peek(fiber.HeaderContentEncoding))
e.private = false
e.cacheControl = utils.CopyBytes(cacheControlBytes)
e.expires = utils.CopyBytes(c.Response().Header.Peek(fiber.HeaderExpires))
e.etag = utils.CopyBytes(c.Response().Header.Peek(fiber.HeaderETag))
e.date = 0View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Stabilize the storage backend immediately — both reads and writes are failing; check connectivity, capacity, and pool sizing.
- Lift cfg.MaxBytes to reduce eviction frequency (set 0 for unbounded) while the backend recovers.
- Scale the cache backend (cluster size, throughput) to match write load.
- After recovery, flush storage and restart so heap indices and stored entries are consistent.
Example fix
// before: bounded cache + failing storage -> joined delete/restore error
cfg := cache.Config{Storage: failingRedis, MaxBytes: 1 << 16}
// after: unbounded budget while backend recovers + healthy storage
cfg := cache.Config{
Storage: healthyRedis,
MaxBytes: 0, // or a much larger budget
Expiration: 10 * time.Minute,
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight write+delete check against storage before enabling bounded cache.
func pingStorageFull(s fiber.Storage) error {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if err := s.Set(ctx, "__p__", []byte("1"), 5*time.Second); err != nil {
return err
}
return s.Delete(ctx, "__p__")
} Type guard
null
Try / catch
app.Use(func(c fiber.Ctx) error {
err := c.Next()
if err != nil && strings.Contains(err.Error(), "while evicting") {
// compound eviction failure — storage is degraded
log.Errorf("cache eviction compound failure: %v", err)
return c.Status(fiber.StatusServiceUnavailable).SendString("cache degraded")
}
return err
}) Prevention
- Monitor storage health and fail fast at startup if writes/deletes are unhealthy.
- Raise cfg.MaxBytes (or set 0 for unbounded) to lower eviction churn.
- Scale the storage backend to match write load and concurrency.
- Flush + restart after any sustained storage outage to resync heap and storage.
When it happens
Trigger: cfg.MaxBytes > 0, a new write triggers eviction; the storage Delete for the chosen victim fails; the recovery loop re-adds victims to the heap and calls refreshHeapIndex which itself fails on get or set. Reproducible by making storage Delete and get/set both fail during a write that requires eviction.
Common situations: Storage backend (Redis) goes read/write-unavailable mid-write during high eviction churn; disk full so both Delete and set fail; TLS to storage expired; storage pool exhausted under concurrent cache pressure.
Related errors
- cache: failed to reload key %q after eviction failure: %w
- cache: failed to restore heap index for key %q: %w
- cache: failed to delete expired key %q: %w
- cache: failed to delete private response for key %q: %w
- cache: failed to delete cached response for key %q: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/a596b5c6634e24a1.json.
Report an issue: GitHub.