Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redis Error: WRONGTYPE Operation against a key holding the wrong kind of value #93

Closed
avia-w opened this issue Aug 29, 2023 · 1 comment

Comments

@avia-w
Copy link

avia-w commented Aug 29, 2023

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

@cristipufu
Copy link
Owner

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
               });               

@cristipufu cristipufu changed the title Redis Error Redis Error: WRONGTYPE Operation against a key holding the wrong kind of value Aug 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants