The NOSCRIPT error occurs when Redis tries to execute a Lua script using EVALSHA but the script isn't cached on the server. Learn how to properly load scripts and handle this common issue.
Redis allows you to execute custom Lua scripts using two commands: EVAL (which sends the full script source) and EVALSHA (which sends only the SHA1 hash of the script). When you use EVALSHA, Redis expects the script to already be cached in memory. The NOSCRIPT error indicates that Redis received an EVALSHA command with a script hash it doesn't recognize. This means either: 1. The script was never loaded with SCRIPT LOAD 2. The Redis server was restarted (clearing the script cache) 3. The script cache was flushed with SCRIPT FLUSH 4. A different Redis instance was targeted that doesn't have the script Unlike persistent data, Redis script caches are not durable across restarts. The script cache is cleared whenever the server restarts or is explicitly flushed.
Check if the script hash exists in Redis cache. Replace SHA1_HASH with the actual SHA1 hash of your Lua script.
# Check if script is loaded
redis-cli SCRIPT EXISTS SHA1_HASH
# Returns 1 if script exists, 0 if not foundIf the command returns 0, the script isn't cached and needs to be loaded.
If the script doesn't exist, load it into Redis cache. This will return the SHA1 hash of the script.
redis-cli SCRIPT LOAD "return redis.call('get', KEYS[1])"Save the returned SHA1 hash. You'll use this hash with EVALSHA commands.
Most modern Redis client libraries have built-in support for handling NOSCRIPT errors. Use the library's Script wrapper if available.
For example, in redis-py:
from redis import Redis
from redis.commands.core import Script
redis = Redis()
# Use the Script object which automatically handles NOSCRIPT
script = redis.register_script("return redis.call('get', KEYS[1])")
result = script(keys=['my-key'])The Script object will:
1. Try EVALSHA first (fast)
2. Catch NOSCRIPT error if returned
3. Load script with SCRIPT LOAD
4. Retry with EVALSHA
This pattern is reliable and handles all edge cases.
For mission-critical scripts, use EVAL instead of EVALSHA. This trades bandwidth for reliability since the full script source is sent each time, but the script is always available.
redis-cli EVAL "return redis.call('get', KEYS[1])" 1 my-keyEVAL automatically caches the script, so subsequent EVALSHA calls will work. Use this approach when you need guaranteed script execution.
When using pipelined commands with scripts, pre-load all scripts at application startup. This prevents NOSCRIPT errors in pipelines where errors can't be retried.
import redis
redis_client = redis.Redis()
# Pre-load scripts at startup
script_hashes = {}
scripts = {
'get_and_increment': "return redis.call('incr', KEYS[1])",
'atomic_swap': "return {redis.call('get', KEYS[1]), redis.call('set', KEYS[1], ARGV[1])}"
}
for name, source in scripts.items():
script_hashes[name] = redis_client.script_load(source)
# Now use in pipelines
pipe = redis_client.pipeline()
pipe.evalsha(script_hashes['get_and_increment'], 1, 'counter')
pipe.evalsha(script_hashes['atomic_swap'], 1, 'value', 'new_value')
results = pipe.execute()This ensures scripts are available before any pipeline execution attempts them.
Pipelined Commands Special Case: When using EVALSHA in a Redis pipeline or transaction (MULTI/EXEC), errors can't be handled the same way as single commands. If EVALSHA returns NOSCRIPT in a pipeline, you can't retry the command because it would break the pipeline order. Solution: Pre-load all scripts with SCRIPT LOAD before starting the pipeline, or use EVAL with full script source inside pipelines.
Script Cache Memory: Script caches consume memory on the server, but Redis doesn't evict scripts under normal memory pressure. However, if Redis runs critically low on memory, scripts may be evicted. Monitor your Redis memory usage and consider pre-loading frequently-used scripts at startup.
Replication and Failover: Script caches are not replicated across Redis cluster nodes or between primary/replica instances. If your application uses Redis replication or clustering, ensure scripts are loaded on all instances, or handle NOSCRIPT errors gracefully with fallback logic.
SCRIPT FLUSH Impact: Be cautious with SCRIPT FLUSH - it clears ALL cached scripts globally. Use it only during maintenance windows or when rotating script versions.
ERR Unbalanced XREAD list of streams
How to fix "ERR Unbalanced XREAD list" in Redis
ERR syntax error
How to fix "ERR syntax error" in Redis
ConnectionError: Error while reading from socket
ConnectionError: Error while reading from socket in redis-py
ERR unknown command
How to fix ERR unknown command in Redis
Command timed out
How to fix 'Command timed out' in ioredis