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

  1. Check the appended inner exception — it will show ConnectionFailure, timeout, or socket errors from StackExchange.Redis
  2. Verify REDIS_ADDR is set to the correct host:port and that Redis responds (redis-cli ping from the same network)
  3. Ensure the Redis instance is running, has memory available, and check for maxmemory/eviction settings
  4. 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

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


AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02). Data as JSON: /api/errors/3641a81460296535. Report an issue: GitHub.