Redis Error: WRONGTYPE Operation against a key holding the wrong kind of value
avia-w opened this issue · 1 comments
I wanted to use this library and did some testing. This was my code:
`services.AddRateLimiter(options =>
{
options.OnRejected = (context, _) =>
{
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
{
context.HttpContext.Response.Headers.RetryAfter =
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
}
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.");
return new ValueTask();
};
options.GlobalLimiter = PartitionedRateLimiter.CreateChained(
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
{
string clientId = GetClientFromContext(httpContext);
return RedisRateLimitPartition.GetFixedWindowRateLimiter(clientId, _ =>
new RedisFixedWindowRateLimiterOptions
{
ConnectionMultiplexerFactory = () => connectionMultiplexer,
PermitLimit = 2,
Window = TimeSpan.FromSeconds(1)
});
}),
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
{
string clientId = GetClientFromContext(httpContext);
return RateLimitPartition.GetNoLimiter(clientId);
}),
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
{
string clientId = GetClientFromContext(httpContext);
return RedisRateLimitPartition.GetConcurrencyRateLimiter(clientId, _ =>
new RedisConcurrencyRateLimiterOptions
{
ConnectionMultiplexerFactory = () => connectionMultiplexer,
PermitLimit = 5,
QueueLimit = 10
});
})
);
});`
It worked as expected for a while, and at some point I started getting this error from Redis:
"ERR Error running script (call to f_a08ae7b80fbefc1d082f3c02f112bb4f38a59fa7): @user_script:8: WRONGTYPE Operation against a key holding the wrong kind of value"
I looked in Redis monitor and saw the error as a result of this command:
"evalsha" "a08ae7b80fbefc1d082f3c02f112bb4f38a59fa7" "3" "rl:{tabdevweb.ini}" "rl:{tabdevweb.ini}:q" "rl:{tabdevweb.ini}:stats" "2" "1000" "0" "1693226580" "rl:{tabdevweb.ini}" "rl:{tabdevweb.ini}:q" "b2ec810f-80ac-4c50-b2b9-e46aad0de33c" "rl:{tabdevweb.ini}:stats"
After a while (next day) the error disappeared and now its working fine again.
Thanks
Hi @avia-w, thanks for taking the time to report this issue.
Given the evalsha command in the error, the issue is arising from a Lua script that's being executed in Redis. The SHA hash (a08ae7b80fbefc1d082f3c02f112bb4f38a59fa7) references this Lua script, and something inside that script at line 8 is causing the problem, eg: https://github.com/cristipufu/aspnetcore-redis-rate-limiting/blob/master/src/RedisRateLimiting/Concurrency/RedisConcurrencyManager.cs#L24C13-L24C87
The error WRONGTYPE Operation against a key holding the wrong kind of value
would occur if @rate_limit_key
is not holding a sorted set (zset).
It looks like you're using multiple rate limiters with the same cache key (fixed window + concurrency with the same clientId key).
You need to differentiate between these rate limiters, you could, for example, add a prefix to the clientId identifier:
return RedisRateLimitPartition.GetFixedWindowRateLimiter($"fw{clientId}", _ =>
new RedisFixedWindowRateLimiterOptions
{
ConnectionMultiplexerFactory = () => connectionMultiplexer,
PermitLimit = 2,
Window = TimeSpan.FromSeconds(1)
});
return RedisRateLimitPartition.GetConcurrencyRateLimiter($"cc{clientId}", _ =>
new RedisConcurrencyRateLimiterOptions
{
ConnectionMultiplexerFactory = () => connectionMultiplexer,
PermitLimit = 5,
QueueLimit = 10
});