{"id":"f31003201f50bb59","repo":"gofiber/fiber","slug":"cache-failed-to-delete-stale-vary-manifest-q-w","errorCode":null,"errorMessage":"cache: failed to delete stale vary manifest %q: %w","messagePattern":"cache: failed to delete stale vary manifest %q: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"middleware/cache/cache.go","lineNumber":551,"sourceCode":"\t\t\tif e != nil {\n\t\t\t\tif err := deleteKey(reqCtx, key); err != nil {\n\t\t\t\t\tif cfg.Storage != nil {\n\t\t\t\t\t\tmanager.release(e)\n\t\t\t\t\t}\n\t\t\t\t\treturn fmt.Errorf(\"cache: failed to delete cached response for key %q: %w\", maskKey(key), err)\n\t\t\t\t}\n\t\t\t\tmux.Lock()\n\t\t\t\tremoveHeapEntry(key, e.heapidx)\n\t\t\t\tif cfg.Storage != nil {\n\t\t\t\t\tmanager.release(e)\n\t\t\t\t}\n\t\t\t\te = nil\n\t\t\t\tmux.Unlock()\n\t\t\t}\n\n\t\t\tif !cfg.DisableVaryHeaders && hasVaryManifest {\n\t\t\t\tif err := manager.del(reqCtx, manifestKey); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"cache: failed to delete stale vary manifest %q: %w\", maskKey(manifestKey), err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.Set(cfg.CacheHeader, cacheUnreachable)\n\t\t\treturn nil\n\t\t}\n\n\t\tshouldStoreVaryManifest := !cfg.DisableVaryHeaders && len(varyNames) > 0\n\t\tif !cfg.DisableVaryHeaders && len(varyNames) > 0 {\n\t\t\tif key == baseKey {\n\t\t\t\tkey += buildVaryKey(varyNames, &c.Request().Header)\n\t\t\t}\n\t\t} else if !cfg.DisableVaryHeaders && hasVaryManifest {\n\t\t\tif err := manager.del(reqCtx, manifestKey); err != nil {\n\t\t\t\treturn fmt.Errorf(\"cache: failed to delete stale vary manifest %q: %w\", maskKey(manifestKey), err)\n\t\t\t}\n\t\t}\n","sourceCodeStart":533,"sourceCodeEnd":569,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/cache/cache.go#L533-L569","documentation":"On the same response path as 134, after marking the response uncacheable: if Vary header tracking is enabled and a stale vary manifest previously existed for this base key, Fiber calls manager.del(manifestKey) to remove it; failure returns this error. The manifest is the per-base-key index of Vary-driven sub-partitions, so leaving it stale can cause future lookups to mis-partition.","triggerScenarios":"DisableVaryHeaders is false, hasVaryManifest is true, response is uncacheable (private/no-cache/Vary:*), and manager.del of the manifestKey fails. Reproducible by storing a varied response, then sending an uncacheable response for the same base key while breaking storage Delete.","commonSituations":"Vary-aware caching where the upstream changes a route to private/no-cache while old vary manifests linger; remote storage Delete hiccups during the transition; concurrent requests racing to mutate the same manifestKey.","solutions":["Diagnose the wrapped storage Delete error and stabilize the backend.","If Vary partitioning isn't needed, set DisableVaryHeaders: true to skip manifest bookkeeping entirely.","Flush stale manifests by clearing the storage namespace after policy changes.","Reduce concurrent races by narrowing cfg.Methods / cfg.Next so only stable cacheable routes participate."],"exampleFix":"// before: vary manifests accumulate and Delete fails\ncfg := cache.Config{Storage: flakyStorage}\n\n// after: disable vary bookkeeping where not needed + healthy storage\ncfg := cache.Config{\n  Storage:            robustStorage,\n  DisableVaryHeaders: true,\n}","handlingStrategy":"validation","validationCode":"// If vary partitioning isn't needed, disable it to avoid manifest maintenance.\ncfg := cache.Config{DisableVaryHeaders: true}","typeGuard":"null","tryCatchPattern":"app.Use(func(c fiber.Ctx) error {\n    err := c.Next()\n    if err != nil && strings.Contains(err.Error(), \"failed to delete stale vary manifest\") {\n        log.Warnf(\"stale vary manifest purge failed: %v\", err)\n        return nil\n    }\n    return err\n})","preventionTips":["Set DisableVaryHeaders: true when Vary partitioning isn't required.","Keep Vary header usage consistent across responses for the same route.","Flush cache storage after changing Vary behavior.","Stabilize storage Delete reliability to avoid manifest orphans."],"tags":["cache","storage","vary","manifest","delete"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}