gofiber/fiber · warning
cache: failed to delete cached response for key
Error message
cache: failed to delete cached response for key %q: %w
What it means
Returned from the response-storage path when, after deciding the response must NOT be cached (hasPrivate || hasNoCache || varyHasStar), Fiber attempts to delete a previously-stored entry for that key and deleteKey fails. RFC 9111 requires Vary: * and private/no-cache responses to stay out of the cache, so any prior entry is purged; storage failure here is surfaced as an error rather than silently leaving stale data.
Solutions
- Verify the upstream Cache-Control / Vary policy is what you intended (no-cache/private/Vary:* may be a misconfiguration).
- Diagnose the wrapped delete error against the storage backend.
- Ensure storage connectivity and delete permissions for the cache namespace.
- If Vary: * is intentional, accept that the response is uncacheable and the prior entry purge must succeed; harden storage.
- Add storage delete monitoring to catch the underlying cause.
Example fix
// before: upstream set Vary: * by mistake, causing repeated purge churn Cache-Control: private Vary: * // after: scope Vary to actual headers Vary: Authorization
Defensive patterns
Strategy: validation
Validate before calling
// Audit upstream Cache-Control/Vary policy so the cache does not churn.
func classify(respHeaders http.Header) string {
cc := respHeaders.Get("Cache-Control")
switch {
case strings.Contains(cc, "no-cache"): return "no-cache"
case strings.Contains(cc, "private"): return "private"
case respHeaders.Get("Vary") == "*": return "vary:*"
}
return "cacheable"
} Try / catch
app.Use(func(c fiber.Ctx) error {
err := c.Next()
if err != nil && isCacheUncacheableDeleteErr(err) {
// origin said do-not-cache; serve uncached and move on
return nil
}
return err
}) Prevention
- Verify upstream Cache-Control and Vary are intentional.
- Avoid Vary: * unless you really mean 'never cache'.
- Stabilize the policy per route to reduce purge churn.
- Harden storage delete connectivity.
When it happens
Trigger: A key that previously held a cacheable response is now classified uncacheable (origin returned Cache-Control: no-cache, private, or Vary: *), and the storage Delete fails. The error halts further processing of this response's storage; the heap entry is removed in-memory and the entry released before returning.
Common situations: Origin changed its Cache-Control policy for a route; storage backend briefly unavailable during policy transition; Vary header set to '*' by mistake in upstream; first private response after a long run of public ones.
Related errors
- cache: failed to delete private response for key
- cache: failed to delete stale vary manifest
- cache: failed to delete expired key
- cache: failed to delete key
- cache: failed to delete key
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/dcfd2e94b80aacf1.
Report an issue: GitHub.
Appendix: source
Thrown at middleware/cache/cache.go:620
hasPrivate := respCacheControl.hasPrivate
hasNoCache := respCacheControl.hasNoCache
varyNames, varyHasStar := parseVary(varyHeader)
// Respect server cache-control: no-store
if respCacheControl.hasNoStore {
markUnreachable()
return nil
}
// RFC 9111 requires responses with Vary: * to remain uncacheable even when
// response-driven Vary partitioning is otherwise disabled.
if hasPrivate || hasNoCache || varyHasStar {
if e != nil {
if err := deleteKey(reqCtx, key); err != nil {
if cfg.Storage != nil {
manager.release(e)
}
return fmt.Errorf("cache: failed to delete cached response for key %q: %w", maskKey(key), err)
}
mux.Lock()
removeHeapEntry(key, e.heapidx)
if cfg.Storage != nil {
manager.release(e)
}
e = nil
mux.Unlock()
}
if !cfg.DisableVaryHeaders && hasVaryManifest {
if err := manager.del(reqCtx, manifestKey); err != nil {
return fmt.Errorf("cache: failed to delete stale vary manifest %q: %w", maskKey(manifestKey), err)
}
}
c.Set(cfg.CacheHeader, cacheUnreachable)
return nilView on GitHub (pinned to a105acad6c)