Fixing 'ERR Script attempted to access a non-local key' in Redis Cluster

intermediate🔴 Redis2026-06-23| Redis Cluster (v3.0 and above), Linux (Ubuntu/CentOS), Docker, or Managed Redis (AWS ElastiCache, Azure Cache for Redis).

Error Message

ERR Script attempted to access a non-local key in a cluster node
#redis-cluster#lua#scripting#devops

Why You're Seeing This ErrorMoving from a standalone Redis instance to a cluster often feels like a smooth transition—until you try to run a Lua script. Suddenly, your EVAL command crashes. You get a frustrating error: ERR Script attempted to access a non-local key in a cluster node. This happens because a cluster is a distributed system where data is scattered across multiple nodes. Unlike a single instance, a cluster node only 'owns' a specific slice of your data.

The Root Cause: Data Sharding and Hash SlotsRedis Cluster divides the keyspace into exactly 16,384 hash slots. Each node handles a specific range of these slots. For example, Node A might handle slots 0 to 5,460, while Node B takes 5,461 to 10,922. When you run a Lua script, Redis requires that every key the script touches must live in the same hash slot.

The error triggers in these scenarios:

  • Your script tries to read key_a from Node 1 and key_b from Node 2.- You hardcoded a key name inside the script that doesn't belong to the node receiving the command.- You passed keys as arguments that hash to different slots.Redis enforces this rule strictly to maintain atomicity. If a script could touch keys across different nodes, Redis would have to implement expensive cross-node locking, which would destroy performance.

How to Fix the Error### Solution 1: Use Hash Tags for Key GroupingThe most reliable fix is using Hash Tags. By wrapping part of a key name in curly braces {}, you tell Redis to only hash the text inside those braces. This forces different keys to land in the same slot on the same node.

Example: Instead of these keys, which could end up on three different nodes:

user:123:profile
user:123:settings
user:123:stats

Use hash tags to group them together:

{user:123}:profile
{user:123}:settings
{user:123}:stats

Now, Redis hashes only the string user:123. This ensures all three keys live in the same slot, making them accessible to a single Lua script.

Solution 2: Always Pass Keys via the KEYS ArrayRedis Cluster needs to know which keys a script will touch before it actually runs. This allows the client to route the request to the correct node. If you hardcode a key inside your Lua code, the cluster cannot validate the location beforehand.

The Wrong Way (Hardcoded):

-- This will likely fail in a cluster environment
local val = redis.call('GET', 'global_settings')
return val

The Right Way (Passed as Argument):

-- Pass 'global_settings' as KEYS[1] from your application code
local val = redis.call('GET', KEYS[1])
return val

When you use the KEYS array, cluster-aware clients like ioredis, lettuce, or redis-py calculate the slot first. They then send the script to the specific node that holds that key.

Solution 3: Move Logic to the Application LayerSometimes you simply cannot co-locate keys. If you need to compare data between two users who live in different slots, a single Lua script won't work. In this case, you must handle the logic in your application code:

  • Fetch user:123:data from Redis.- Fetch user:456:data from Redis.- Perform your comparison or logic in Node.js, Go, or Python.- Write the results back to Redis if needed.## Verification StepsCheck if your keys share the same slot using the cluster keyslot command in redis-cli:
# Check slot for the profile key
redis-cli -c CLUSTER KEYSLOT {user:123}:profile
# Output: 1234

# Check slot for the settings key
redis-cli -c CLUSTER KEYSLOT {user:123}:settings
# Output: 1234

If the output numbers match, your script will run without errors.

Prevention Best Practices- Design for Sharding: Identify keys that are frequently updated together and use hash tags to keep them on the same node.- Use Cluster-Aware Clients: Ensure your library supports Redis Cluster and automatically calculates hash slots.- Audit Your Scripts: Never use string concatenation inside Lua to build key names. If a key isn't in the KEYS array, it shouldn't be in your script.- Avoid Global Keys: Don't mix 'global' configuration keys with user-specific data in the same script, as they will almost certainly reside on different nodes.

Related Error Notes