{"record":{"id":"67c5ac08fafc3b7f","repo":"gofiber/fiber","slug":"cache-failed-to-get-key-q-from-storage-w","errorCode":null,"errorMessage":"cache: failed to get key %q from storage: %w","messagePattern":"cache: failed to get key %q from storage: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"middleware/cache/manager.go","lineNumber":114,"sourceCode":"\te.status = 0\n\te.age = 0\n\te.exp = 0\n\te.ttl = 0\n\te.forceRevalidate = false\n\te.revalidate = false\n\te.headers = nil\n\te.shareable = false\n\te.private = false\n\te.heapidx = 0\n\tm.pool.Put(e)\n}\n\n// get data from storage or memory\nfunc (m *manager) get(ctx context.Context, key string) (*item, error) {\n\tif m.storage != nil {\n\t\traw, err := m.storage.GetWithContext(ctx, key)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cache: failed to get key %q from storage: %w\", m.logKey(key), err)\n\t\t}\n\t\tif raw == nil {\n\t\t\treturn nil, errCacheMiss\n\t\t}\n\n\t\tit := m.acquire()\n\t\tif _, err := it.UnmarshalMsg(raw); err != nil {\n\t\t\tm.release(it)\n\t\t\treturn nil, fmt.Errorf(\"cache: failed to unmarshal key %q: %w\", m.logKey(key), err)\n\t\t}\n\n\t\treturn it, nil\n\t}\n\n\tif value := m.memory.Get(key); value != nil {\n\t\tit, ok := value.(*item)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"cache: unexpected entry type %T for key %q\", value, m.logKey(key))","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/cache/manager.go#L96-L132","documentation":"Returned by manager.get when an external Storage backend's GetWithContext call errors while fetching a cached item. This is the cache-read path: the middleware tried to retrieve a previously stored response from the configured Storage and the backend reported a failure (not a miss — a miss returns errCacheMiss when raw==nil).","triggerScenarios":"Any cache lookup (GET request hitting the cache middleware with a populated cfg.Storage) where Storage.GetWithContext returns a non-nil error: Redis unreachable, connection pool exhausted, storage backend returning a protocol/deserialization error, context canceled or deadline exceeded.","commonSituations":"Redis/Valkey connection dropped or misconfigured (wrong address/auth); storage driver timeout shorter than load; TLS handshake failures to managed Redis; context cancellation from client disconnect propagating into the storage call; storage backend OOM or failover.","solutions":["Check the wrapped error — for context cancellation (errors.Is(err, context.Canceled|context.DeadlineExceeded)) the client disconnected; no action needed.","Verify Storage connectivity and credentials (ping the backend directly outside Fiber).","Tune the Storage driver's connection pool, dial/read/write timeouts to match your latency budget.","If recurring, add health checks / circuit-breaking around the Storage so transient outages degrade gracefully to uncached responses instead of erroring."],"exampleFix":"// The cache middleware should treat storage errors as a miss, not a request failure:\n// before\nraw, err := m.storage.GetWithContext(ctx, key)\nif err != nil {\n    return nil, fmt.Errorf(\"cache: failed to get key %q from storage: %w\", m.logKey(key), err)\n}\n\n// after (defensive fallback to miss on transient storage errors)\nraw, err := m.storage.GetWithContext(ctx, key)\nif err != nil {\n    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n        return nil, err // propagate only client-driven cancellation\n    }\n    log.Warn(\"cache storage get failed, treating as miss:\", err)\n    return nil, errCacheMiss\n}","handlingStrategy":"retry","validationCode":"// Before serving traffic, confirm Storage is reachable and the key namespace is clean.\nfunc checkCacheStorage(ctx context.Context, s fiber.Storage) error {\n    probe := []byte(\"ok\")\n    if err := s.SetWithContext(ctx, \"__cache_probe__\", probe, time.Second); err != nil {\n        return fmt.Errorf(\"storage write check failed: %w\", err)\n    }\n    got, err := s.GetWithContext(ctx, \"__cache_probe__\")\n    if err != nil {\n        return fmt.Errorf(\"storage read check failed: %w\", err)\n    }\n    if !bytes.Equal(got, probe) {\n        return fmt.Errorf(\"storage roundtrip mismatch\")\n    }\n    _ = s.DeleteWithContext(ctx, \"__cache_probe__\")\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Classify before acting: cancellation propagates, other errors degrade to miss.\nraw, err := m.storage.GetWithContext(ctx, key)\nif err != nil {\n    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n        return nil, err\n    }\n    // transient storage error -> treat as miss, optionally retry once\n    return nil, errCacheMiss\n}","preventionTips":["Run a startup probe against the configured Storage before serving requests.","Size the Storage connection pool and timeouts to your p99 latency.","Log storage errors with the wrapped cause to distinguish transient from permanent failures."],"tags":["cache","storage","network","go","fiber","external-storage"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}