GoogleCloudPlatform/microservices-demo · critical · RpcException
FAILED_PRECONDITION
FAILED_PRECONDITION
Error message
Can't access cart storage. {ex} What it means
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.
Source
Thrown at src/cartservice/src/cartstore/RedisCartStore.cs:64
}
else
{
cart = Hipstershop.Cart.Parser.ParseFrom(value);
var existingItem = cart.Items.SingleOrDefault(i => i.ProductId == productId);
if (existingItem == null)
{
cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity });
}
else
{
existingItem.Quantity += quantity;
}
}
await _cache.SetAsync(userId, cart.ToByteArray());
}
catch (Exception ex)
{
throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}"));
}
}
public async Task EmptyCartAsync(string userId)
{
Console.WriteLine($"EmptyCartAsync called with userId={userId}");
try
{
var cart = new Hipstershop.Cart();
await _cache.SetAsync(userId, cart.ToByteArray());
}
catch (Exception ex)
{
throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}"));
}
}
View on GitHub (pinned to 72ba613a05)
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
Example fix
// before REDIS_ADDR= # unset // after REDIS_ADDR=redis-cart.cartservice.svc.cluster.local:6379
Defensive patterns
Strategy: retry
Validate before calling
// Node/C# caller: probe Redis before AddItem via the store's Ping()
if (!cartStore.Ping()) {
throw new InvalidOperationException("Redis cart storage is unreachable; check REDIS_ADDR.");
} Type guard
bool IsRedisCartFailure(RpcException ex) =>
ex.StatusCode == StatusCode.FailedPrecondition &&
ex.Status.Detail.StartsWith("Can't access cart storage"); Try / catch
try {
await cartStore.AddItemAsync(userId, productId, quantity, 1);
} catch (RpcException ex) when (IsRedisCartFailure(ex)) {
await Task.Delay(500);
await cartStore.AddItemAsync(userId, productId, quantity, 1); // one retry for transient Redis blips
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- FAILED_PRECONDITION
- FAILED_PRECONDITION
- failed to get user cart during checkout: %+v
- failed to empty user cart during checkout: %+v
- InvalidCreditCard
AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02).
Data as JSON: /api/errors/3641a81460296535.
Report an issue: GitHub.