{"record":{"id":"3641a81460296535","repo":"GoogleCloudPlatform/microservices-demo","slug":"failed-precondition-3641a8","errorCode":"FAILED_PRECONDITION","errorMessage":"Can't access cart storage. {ex}","messagePattern":"Can't access cart storage\\. (.+?)","errorType":"error_code","errorClass":"RpcException","httpStatus":null,"severity":"critical","filePath":"src/cartservice/src/cartstore/RedisCartStore.cs","lineNumber":64,"sourceCode":"                }\n                else\n                {\n                    cart = Hipstershop.Cart.Parser.ParseFrom(value);\n                    var existingItem = cart.Items.SingleOrDefault(i => i.ProductId == productId);\n                    if (existingItem == null)\n                    {\n                        cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity });\n                    }\n                    else\n                    {\n                        existingItem.Quantity += quantity;\n                    }\n                }\n                await _cache.SetAsync(userId, cart.ToByteArray());\n            }\n            catch (Exception ex)\n            {\n                throw new RpcException(new Status(StatusCode.FailedPrecondition, $\"Can't access cart storage. {ex}\"));\n            }\n        }\n\n        public async Task EmptyCartAsync(string userId)\n        {\n            Console.WriteLine($\"EmptyCartAsync called with userId={userId}\");\n\n            try\n            {\n                var cart = new Hipstershop.Cart();\n                await _cache.SetAsync(userId, cart.ToByteArray());\n            }\n            catch (Exception ex)\n            {\n                throw new RpcException(new Status(StatusCode.FailedPrecondition, $\"Can't access cart storage. {ex}\"));\n            }\n        }\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/GoogleCloudPlatform/microservices-demo/blob/72ba613a05f7fcee51cf1d0badff401b6ae7074d/src/cartservice/src/cartstore/RedisCartStore.cs#L46-L82","documentation":"RedisCartStore.AddItemAsync catches any failure while reading the cached cart or writing the updated cart bytes back to Redis and rethrows as an RpcException with StatusCode.FailedPrecondition and message 'Can't access cart storage. {ex}'. It means the Redis-backed cart store could not be reached or the SET/GET on the user's cart failed, so the item was not added.","triggerScenarios":"AddItemAsync fails on StackExchange.Redis GetDatabase()/GET/SET operations: REDIS_ADDR wrong, Redis down/restarting, connection multiplexer not initialized, or serialization issues writing the cart protobuf.","commonSituations":"REDIS_ADDR env var unset or pointing at a nonexistent host; Redis pod OOM-killed or under memory pressure (maxmemory eviction); auth/ACL enabled on Redis without matching password config; DNS issues in the cluster.","solutions":["Check the appended inner exception — it will show ConnectionFailure, timeout, or socket errors from StackExchange.Redis","Verify REDIS_ADDR is set to the correct host:port and that Redis responds (redis-cli ping from the same network)","Ensure the Redis instance is running, has memory available, and check for maxmemory/eviction settings","If using the in-cluster default, confirm the redis service DNS name resolves from the cart service pod"],"exampleFix":"// before\nREDIS_ADDR=  # unset\n// after\nREDIS_ADDR=redis-cart.cartservice.svc.cluster.local:6379","handlingStrategy":"retry","validationCode":"// Node/C# caller: probe Redis before AddItem via the store's Ping()\nif (!cartStore.Ping()) {\n    throw new InvalidOperationException(\"Redis cart storage is unreachable; check REDIS_ADDR.\");\n}","typeGuard":"bool IsRedisCartFailure(RpcException ex) =>\n    ex.StatusCode == StatusCode.FailedPrecondition &&\n    ex.Status.Detail.StartsWith(\"Can't access cart storage\");","tryCatchPattern":"try {\n    await cartStore.AddItemAsync(userId, productId, quantity, 1);\n} catch (RpcException ex) when (IsRedisCartFailure(ex)) {\n    await Task.Delay(500);\n    await cartStore.AddItemAsync(userId, productId, quantity, 1); // one retry for transient Redis blips\n}","preventionTips":["Set REDIS_ADDR explicitly in every deployment (e.g. redis-cart:6379)","Deploy Redis with memory limits headroom and non-evicting policy for cart keys","Use Ping() in readiness probes so the pod is removed from rotation when Redis is down","Re-initialize the ConnectionMultiplexer on Redis restarts; monitor Redis reconnect events"],"tags":["grpc","redis","cartservice","dotnet","network"],"backgroundTag":"cart-storage-unavailable","analyzedSha":"72ba613a05f7fcee51cf1d0badff401b6ae7074d","analyzedAt":"2026-09-02T01:15:09.673Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}