Fix: Valkey Not Working — Redis Client Compatibility, ACL, Cluster Mode, and Migration
Quick Answer
How to fix Valkey errors — client connection refused, RESP protocol compatibility, ACL user setup, cluster slot reshard, persistence config (RDB/AOF), TLS, Sentinel mode, and migrating from Redis.
The Error
You point your Redis client at Valkey and the connection works but a command fails:
import redis
r = redis.Redis(host="valkey.internal", port=6379)
r.json().set("user:1", "$", {"name": "Alice"})
# redis.exceptions.ResponseError: unknown command 'JSON.SET'Or ACL authentication fails after enabling auth:
NOAUTH Authentication required.Or a cluster command times out:
CLUSTERDOWN The cluster is downOr you migrate from Redis and persistence files are gone:
$ ls /var/lib/valkey/
# Empty — old /var/lib/redis/ files weren't migrated.Why This Happens
Valkey is a community fork of Redis (BSD-licensed) that picks up after Redis 7.2.4. It’s nearly drop-in compatible:
- RESP protocol unchanged. Every Redis client (
redis-py,ioredis,go-redis,Jedis,lettuce) connects to Valkey without modification. - Most commands identical. SET, GET, HSET, LPUSH, SUBSCRIBE — all work. Some Redis-Stack modules (RedisJSON, RedisSearch, RedisTimeSeries) are not in Valkey by default; you’d add them as modules or use alternatives.
- ACL system identical. Same
ACL SETUSER, same passwords-hashed-as-SHA256, same key patterns. - Cluster mode identical. Same
CLUSTER SLOTS, same hash slot allocation.
Most “not working” issues come from:
- Assuming RedisJSON / RediSearch are bundled (they’re not — Valkey ships a smaller core).
- Configuration file paths different (
/etc/valkey/valkey.confvs/etc/redis/redis.conf). - Service name change (
systemctl status valkeyvsredis). - Data directory not migrated when switching the binary.
Fix 1: Use Any Redis Client
Your existing Redis client works:
import redis
r = redis.Redis(host="valkey.example.com", port=6379, password="secret")
r.set("key", "value")
print(r.get("key")) # b"value"import Redis from "ioredis";
const r = new Redis({ host: "valkey.example.com", port: 6379, password: "secret" });
await r.set("key", "value");
console.log(await r.get("key"));import "github.com/redis/go-redis/v9"
rdb := redis.NewClient(&redis.Options{
Addr: "valkey.example.com:6379",
Password: "secret",
})
rdb.Set(ctx, "key", "value", 0)No need to swap client libraries. The wire protocol is the same.
Pro Tip: For new code, look for a “Valkey” branded client in your language’s package registry. Some are emerging that drop the Redis trademark. Functionally they’re the same.
Fix 2: Install and Start Valkey
Most distros now package Valkey directly:
# Ubuntu / Debian:
sudo apt-get install valkey-server valkey-tools
# Fedora / RHEL:
sudo dnf install valkey
# macOS:
brew install valkey
# Docker:
docker run -d --name valkey -p 6379:6379 valkey/valkey:8Config file location: /etc/valkey/valkey.conf (Linux), /usr/local/etc/valkey.conf (macOS Homebrew).
Service management:
sudo systemctl start valkey
sudo systemctl enable valkey
sudo systemctl status valkeyFor testing connectivity:
valkey-cli ping
# PONG
valkey-cli -h valkey.example.com -p 6379 -a secret
> SET foo bar
> GET foo
"bar"valkey-cli is the same as redis-cli with the new branding. Either binary connects to either server.
Fix 3: Configure Persistence (RDB / AOF)
Valkey supports both Redis persistence formats:
# /etc/valkey/valkey.conf
# RDB snapshots (default):
save 3600 1 # Save if at least 1 key changed in 3600s
save 300 100 # Save if at least 100 keys changed in 300s
save 60 10000 # Save if at least 10000 keys changed in 60s
dbfilename dump.rdb
dir /var/lib/valkey
# AOF (append-only file) for durability:
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # Sync every second (balanced)
# appendfsync always # Sync every command (slower, more durable)
# appendfsync no # OS decides (fastest, least durable)For most caches, RDB is enough — periodic snapshots, fast restart. For systems where data loss is unacceptable (queues, session stores), enable AOF too.
Restart after config changes:
sudo systemctl restart valkeyCommon Mistake: Migrating from Redis without copying dump.rdb and appendonly.aof. Stop Redis, copy files to Valkey’s dir, start Valkey. The format is fully compatible.
Fix 4: ACL — User and Permission Setup
Valkey supports the Redis 6+ ACL system. Create users:
valkey-cli
> ACL SETUSER alice on >password ~user:* +@read +@write
> ACL SETUSER readonly on >readonly-pass ~* +@read
> ACL LISTBreakdown:
on— user is enabled.>password— set the password.~user:*— keys this user can access (pattern).+@read +@write— command categories allowed.
Persist ACLs in users.acl:
# valkey.conf
aclfile /etc/valkey/users.aclusers.acl:
user default off
user alice on #<sha256-of-password> ~user:* +@read +@write
user admin on #<sha256-of-password> ~* +@allTo disable the default unrestricted user (default):
> ACL SETUSER default offOr set a password on it via requirepass (legacy):
requirepass mysecretCommon Mistake: Forgetting to grant +@read +@write +@connection. Without +@connection, the user can’t even AUTH. Use +@all -@dangerous for a sensible default that excludes admin commands.
Fix 5: Cluster Mode
For Valkey cluster:
# valkey.conf
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yesStart 6 nodes (3 primaries, 3 replicas):
for port in 7000 7001 7002 7003 7004 7005; do
valkey-server --port $port --cluster-enabled yes --cluster-config-file nodes-$port.conf --appendonly yes --daemonize yes
doneCreate the cluster:
valkey-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1Check status:
valkey-cli -p 7000 cluster info
valkey-cli -p 7000 cluster nodesReshard slots:
valkey-cli --cluster reshard 127.0.0.1:7000
# Interactive prompt for slot count and source/target node IDs.Pro Tip: Use hash tags ({user_id}) for related keys you want on the same slot — e.g. user:{42}:profile and user:{42}:settings. Avoids cross-slot transactions.
Fix 6: TLS
# valkey.conf
tls-port 6380
port 0 # Disable non-TLS port
tls-cert-file /etc/valkey/cert.pem
tls-key-file /etc/valkey/key.pem
tls-ca-cert-file /etc/valkey/ca.pem
tls-auth-clients yes # Require client certClient side:
import redis
r = redis.Redis(
host="valkey.example.com",
port=6380,
ssl=True,
ssl_cert_reqs="required",
ssl_ca_certs="/etc/ssl/ca.pem",
ssl_certfile="/etc/ssl/client.pem",
ssl_keyfile="/etc/ssl/client.key",
)For valkey-cli:
valkey-cli --tls --cert cert.pem --key key.pem --cacert ca.pem -h valkey.example.com -p 6380For Sentinel and Cluster with TLS, every node needs certs. Use Let’s Encrypt or a private CA.
Fix 7: Migrate From Redis
To switch from Redis to Valkey:
# 1. Stop Redis
sudo systemctl stop redis
# 2. Copy persistence files
sudo cp /var/lib/redis/dump.rdb /var/lib/valkey/
sudo cp /var/lib/redis/appendonly.aof /var/lib/valkey/ # If AOF was on
sudo chown -R valkey:valkey /var/lib/valkey/
# 3. Copy config (review for differences)
sudo cp /etc/redis/redis.conf /etc/valkey/valkey.conf
# Update paths in valkey.conf:
sudo sed -i 's|/var/lib/redis|/var/lib/valkey|g' /etc/valkey/valkey.conf
sudo sed -i 's|/var/log/redis|/var/log/valkey|g' /etc/valkey/valkey.conf
sudo sed -i 's|/var/run/redis|/var/run/valkey|g' /etc/valkey/valkey.conf
# 4. Start Valkey
sudo systemctl start valkey
sudo systemctl enable valkey
# 5. Verify
valkey-cli ping
valkey-cli dbsizeFor zero-downtime, set up Valkey as a Redis replica first, then promote:
# In valkey.conf:
replicaof <redis-host> 6379Let it sync, then break the replication and switch clients.
Common Mistake: Running Redis and Valkey on the same port simultaneously. They’ll fight over 6379. Pick one or use different ports.
Fix 8: Missing Modules (RedisJSON, RediSearch)
Valkey ships a smaller core than Redis Stack. If your app uses RedisJSON, RediSearch, RedisTimeSeries, etc.:
- RedisJSON → use Valkey’s built-in JSON support (Valkey 8.0+) or store JSON as strings.
- RediSearch → look at community search modules for Valkey, or use a separate search service (Meilisearch, Typesense).
- RedisTimeSeries → store as sorted sets or use a dedicated TSDB.
Some modules build directly against Valkey:
sudo valkey-cli MODULE LOAD /path/to/module.soFor module compatibility, check each module’s docs — most that targeted Redis 7+ work on Valkey unchanged.
Note: Redis Inc.’s proprietary modules (commercial RediSearch, etc.) won’t work on Valkey under any license — they’re commercial Redis offerings. Open-source modules continue to work.
Still Not Working?
A few less-obvious failures:
MISCONF Redis is configured to save RDB snapshots but is currently not able to persist on disk.Same in Valkey. Disk full or permission ondir. Free space or checkchown valkey:valkey /var/lib/valkey/.WRONGTYPE Operation against a key holding the wrong kind of value. A key has a different type than your command expects.TYPE keyshows what’s stored.DEL keythen write the correct type.- Cluster slot count != 16384. Valkey clusters always have 16384 slots. If
CLUSTER SLOTSshows fewer, the cluster isn’t fully set up.CLUSTER ADDSLOTSmissing ones. - High memory after FLUSHDB. Memory isn’t returned to the OS by default. Set
activedefrag yesor restart the process. Could not connect to Valkey at 127.0.0.1:6379: Connection refused. Service not running, wrong bind interface (bind 127.0.0.1only listens on localhost), or firewall blocking.- Sentinel doesn’t fail over. Quorum not reached or
down-after-millisecondstoo high. Tune insentinel.conf. - Lua scripts that worked on Redis 7 fail on Valkey 8. Lua sandbox changes between versions. Test scripts after upgrade and watch for
Script attempted to access nonexistent global variable. - valkey-cli REPL shows old prompt. Some shells cache prompt strings. Open a fresh shell or use
valkey-cli --no-banner.
For related caching, pubsub, and persistence issues, see Redis connection refused, Redis OOM command not allowed, Redis pub sub not working, and Redis wrongtype operation.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Redis Streams Not Working — Consumer Groups, XACK, Pending Entries, MAXLEN, and Claiming
How to fix Redis Streams errors — XADD/XREAD basics, consumer group XGROUP CREATE, XACK for ack, XPENDING for stuck messages, MAXLEN ~ for trimming, XAUTOCLAIM for redelivery, and Cluster hash slot constraints.
Fix: NATS Not Working — Connection Auth, JetStream Streams, Consumer Ack, and Subject Wildcards
How to fix NATS errors — no responders to request, JetStream stream not found, consumer redelivery loop, durable vs ephemeral consumers, subject wildcard mismatch, TLS auth setup, and KV bucket basics.
Fix: Redis Cluster Not Working — MOVED, CROSSSLOT, or Connection Errors
How to fix Redis Cluster errors — MOVED redirects, CROSSSLOT multi-key operations, cluster-aware client setup, hash tags for key grouping, and failover handling.
Fix: Redis Pub/Sub Not Working — Messages Not Received by Subscribers
How to fix Redis Pub/Sub issues — subscriber not receiving messages, channel name mismatches, connection handling, pattern subscriptions, and scaling with multiple processes.