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 = 0

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Stabilize the storage backend immediately — both reads and writes are failing; check connectivity, capacity, and pool sizing.
  2. Lift cfg.MaxBytes to reduce eviction frequency (set 0 for unbounded) while the backend recovers.
  3. Scale the cache backend (cluster size, throughput) to match write load.
  4. 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

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


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/a596b5c6634e24a1.json. Report an issue: GitHub.