Fixing Redis 'ERR no such key' Errors with OBJECT ENCODING and TTL

intermediate🔴 Redis2026-04-30| Redis 5.0, 6.0, 7.0+ on Linux (Ubuntu/CentOS), Docker, or Managed Redis (AWS ElastiCache, GCP Memorystore)

Error Message

ERR no such key
#redis#key#ttl#object-encoding#keyspace

The Problem: Now You See It, Now You Don't

It’s a classic ghost in the machine. You're digging through your Redis instance, hunting for the keys eating up your RAM. You run SCAN, identify a target, and immediately try to check its OBJECT ENCODING or TTL. Instead of the metadata you expect, Redis throws a wrench in your gears:

(error) ERR no such key

It’s jarring because you just saw the key listed a few milliseconds ago. Standard Redis CLI usually returns (nil) or -2 for missing keys. However, libraries and proxies like Twemproxy often convert these into a hard ERR no such key. This happens if the key expires at the exact moment of execution.

Analysis: Why the Key Disappeared

Usually, three main culprits are behind this vanishing act.

1. The Race Condition (TTL Expiration)

This is the prime suspect. If you are inspecting session tokens or temporary locks with short lifetimes (e.g., 500ms), the key might expire between your first and second command. Redis is fast, but it isn't instantaneous. Network latency of even 10ms can turn a nearing expiration into a dead end.

2. Invisible Characters and Encoding Gremlins

Look closer at the string. If you copy-paste a key from a log, you might be grabbing hidden characters like trailing spaces, newlines, or null bytes. To Redis, "user:100" and "user:100\r" are entirely different entities. If your code accidentally appends a carriage return, the standard TTL "user:100" command will fail every time.

3. Logic in Lua Scripts

When you run redis.call() inside a Lua script, Redis handles errors strictly. If your script expects a key to exist but it has already expired, the entire script might crash with the no such key error. This is common in scripts that don't verify existence before performing metadata operations.

Quick Fix: Handling the Missing Key

If you're seeing this in the CLI, the "fix" is simply accepting that the key has already expired. For automation or monitoring tools, you must build more resilience. Don't run OBJECT ENCODING blindly.

Try using a Lua one-liner to safely fetch metadata. This ensures both checks happen in the same atomic operation:

EVAL "if redis.call('EXISTS', KEYS[1]) == 1 then return redis.call('OBJECT', 'ENCODING', KEYS[1]) else return nil end" 1 my_key

For TTL, remember that a return value of -2 means the key is gone. If your application library throws an exception instead of returning -2, you should catch that specific error or wrap the call in a safety check.

Permanent Fix: Robust Code Patterns

Improve Your Lua Scripts

Never assume an argument exists. Use redis.call('EXISTS', KEYS[1]) before you touch any metadata. This prevents scripts from terminating early and leaving your application in an inconsistent state.

-- Example of a safe metadata check
if redis.call("EXISTS", KEYS[1]) == 1 then
    return {
        redis.call("OBJECT", "ENCODING", KEYS[1]),
        redis.call("TTL", KEYS[1])
    }
else
    return nil
end

Sanitize Your Key Names

Hidden bytes are a nightmare to debug. This happens often when keys are generated from binary data or URLs. If a key appears twice in a SCAN result but looks identical, you've found a hidden character.

Pro Tip: I've wasted hours chasing "missing" keys only to find a trailing \n in my Python logs. Use a tool like ToolCraft's Base64 Encoder to inspect the raw string. By encoding the key name into Base64, you can spot the hidden bytes that your terminal won't show you.

Check Your Redis Proxy Configuration

Proxies like Envoy or Nutcracker sometimes try to be "helpful." They might turn a nil response into an error to alert you of a potential cache miss. If this behavior is breaking your app, check your proxy configuration or update your application logic to handle these specific error strings gracefully.

Verification: How to Confirm the Fix

Simulate a race condition to ensure your new logic holds up:

  • Create a short-lived key: SET temp_key "test" EX 2 (expires in 2 seconds).
  • Wait briefly: Wait 3 seconds.
  • Run your check: Execute your updated Lua script or wrapper.
  • Verify the output: You should see a controlled (nil) or a custom null instead of a crashing ERR no such key.

To squash encoding issues, run redis-cli --raw SCAN 0. This preserves those sneaky invisible characters, making them much easier to identify and remove from your key generation logic.

Related Error Notes