Skip to content

Redis scaler Lua script fails on Alibaba Cloud Redis Cluster due to variable command name #7758

Description

@cxhello

Report

The Redis scaler's Lua script uses a variable as the first argument to redis.call(), which fails on Alibaba Cloud Redis Cluster instances.

The current Lua script in pkg/scalers/redis_scaler.go:

local cmd = {
    zset = 'zcard',
    set = 'scard',
    list = 'llen',
    hash = 'hlen',
    none = 'llen'
}
return redis.call(cmd[listType], listName)

cmd[listType] is a table lookup result (variable), not a literal string. Alibaba Cloud Redis Cluster's proxy layer enforces strict Lua script validation, requiring the first parameter of redis.call/redis.pcall to be a single literal string.

Expected Behavior

The redis/redis-cluster scaler should work with Alibaba Cloud Redis Cluster instances.

Actual Behavior

ScaledObject enters error state with:

Warning  KEDAScalerFailed  ERR bad lua script for redis cluster, first parameter of redis.call/redis.pcall must be a single literal string

Steps to Reproduce the Problem

  1. Deploy KEDA 2.19.0 on a Kubernetes cluster (e.g., Alibaba Cloud ACK)
  2. Create a ScaledObject with redis or redis-cluster trigger targeting an Alibaba Cloud Redis Cluster instance
  3. The ScaledObject fails with the Lua script error

Logs from KEDA operator

Warning  KEDAScalerFailed  keda-operator  ERR bad lua script for redis cluster, first parameter of redis.call/redis.pcall must be a single literal string

Environment

  • KEDA Version: 2.19.0
  • Kubernetes Version: 1.30 (Alibaba Cloud ACK)
  • Platform: Alibaba Cloud
  • Scaler: redis, redis-cluster

Proposed Fix

Replace the table lookup with if/elseif branches so every redis.call has a literal string as the first argument:

local listName = KEYS[1]
local listType = redis.call('type', listName).ok
if listType == 'zset' then
    return redis.call('zcard', listName)
elseif listType == 'set' then
    return redis.call('scard', listName)
elseif listType == 'hash' then
    return redis.call('hlen', listName)
else
    return redis.call('llen', listName)
end

This is fully compatible with both standard Redis Cluster and Alibaba Cloud Redis Cluster. Happy to submit a PR.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Ready To Ship

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions