This error occurs when attempting to restore or migrate a key using Redis commands like RESTORE or MIGRATE, but a key with that name already exists at the destination. It prevents overwriting the existing key unless the REPLACE option is specified.
The "BUSYKEY Target key name already exists" error indicates that a Redis operation attempted to create or overwrite a key, but a key with that name already exists at the destination and the operation doesn't have permission to overwrite it. This error commonly occurs in two scenarios: - **RESTORE command**: When you use RESTORE to deserialize and store a previously dumped key, Redis will reject the operation if the target key already exists. The RESTORE command by default operates in an atomic manner and refuses to overwrite existing keys to prevent accidental data loss. - **MIGRATE command**: When migrating keys between Redis instances using the MIGRATE command, if the destination Redis instance already has a key with the same name, the migration will fail with this error. This is a safety mechanism to prevent overwriting data without explicit intent. - **Cluster operations**: During cluster import, resharding, or node synchronization, if the target key already exists on the receiving node, Redis will report this error. This commonly happens when retrying failed migration operations without properly cleaning up from previous attempts. The error is intentionally strict to prevent accidental data loss. Redis treats this as a conflict situation rather than automatically replacing the existing key.
First, determine whether the key already exists on the target Redis instance.
If you're restoring locally:
redis-cli EXISTS mykeyIf the result is (integer) 1, the key exists. If it's (integer) 0, it doesn't exist.
For remote instances:
redis-cli -h target-host -p 6379 EXISTS mykeyIf the key exists, you'll need to either delete it or use the REPLACE option in your RESTORE command.
The simplest solution is to add the REPLACE option to your RESTORE command, which allows overwriting the existing key.
Syntax with REPLACE:
RESTORE key ttl serialized-value REPLACEExample - Restoring a string key:
# First, dump the key from source Redis
SOURCE_DATA=$(redis-cli --raw DUMP sourcekey)
# Restore to destination with REPLACE to overwrite if exists
redis-cli -h destination-host RESTORE targetkey 0 "$SOURCE_DATA" REPLACEIn Lua scripts:
local serialized = redis.call('DUMP', 'sourcekey')
redis.call('RESTORE', 'targetkey', 0, serialized, 'REPLACE')With redis-py (Python):
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=False)
serialized = r.dump('sourcekey')
r.execute_command('RESTORE', 'targetkey', 0, serialized, 'REPLACE')With node-redis (JavaScript/TypeScript):
const redis = require('redis');
const client = redis.createClient();
const serialized = await client.dump('sourcekey');
await client.sendCommand(['RESTORE', 'targetkey', '0', serialized, 'REPLACE']);If you want to avoid using REPLACE, you can delete the existing key first. However, be cautious as this removes any data in the existing key.
Delete and then restore:
# Get the serialized data
SOURCE_DATA=$(redis-cli -h source-host DUMP mykey)
# Connect to destination and delete the old key
redis-cli -h destination-host DEL mykey
# Now restore without REPLACE
redis-cli -h destination-host RESTORE mykey 0 "$SOURCE_DATA"Check before deleting (safer approach):
# First, check if the destination key has important data
redis-cli -h destination-host --scan MATCH "mykey"
# View the key type and content
redis-cli -h destination-host TYPE mykey
redis-cli -h destination-host GET mykey
# Only delete if you're sure it's safe
redis-cli -h destination-host DEL mykey
# Then restore
redis-cli -h destination-host RESTORE mykey 0 "$SOURCE_DATA"For cluster resharding, deleting keys is not recommended. Use REPLACE instead.
When migrating keys between Redis instances using MIGRATE, add the REPLACE option to avoid BUSYKEY errors.
MIGRATE syntax with REPLACE:
MIGRATE host port key destination-db timeout REPLACEExample:
# Migrate single key with REPLACE
redis-cli MIGRATE destination-host 6379 mykey 0 5000 REPLACE
# Migrate multiple keys
redis-cli MIGRATE destination-host 6379 key1 0 5000 REPLACE
redis-cli MIGRATE destination-host 6379 key2 0 5000 REPLACEIn a script (migrating all keys matching a pattern):
#!/bin/bash
SOURCE_HOST="source-host"
DEST_HOST="destination-host"
# Get all keys matching pattern
redis-cli -h "$SOURCE_HOST" KEYS "myprefix:*" | while read key; do
echo "Migrating $key..."
redis-cli -h "$SOURCE_HOST" MIGRATE "$DEST_HOST" 6379 "$key" 0 5000 REPLACE
doneWith copy flag (keep key in source):
# MIGRATE also supports COPY flag to keep the key in source
redis-cli MIGRATE destination-host 6379 mykey 0 5000 COPY REPLACEIf you encounter BUSYKEY during Redis cluster resharding or import, follow these steps:
For redis-cli --cluster import:
# Add --cluster-replace flag to allow overwriting keys
redis-cli --cluster import destination:6379 --cluster-from source:6379 --cluster-replace
# Or use --cluster-copy to keep keys in source
redis-cli --cluster import destination:6379 --cluster-from source:6379 --cluster-copy --cluster-replaceFor failed reshard attempts, clean up partial state:
# Connect to the node where resharding failed
redis-cli -h failing-node
# Check the node's current slot configuration
CLUSTER SLOTS
# If a key was partially transferred, check for it
KEYS "*"
# You may need to:
# 1. Clear the partial key: DEL partial_key
# 2. Or flush the slot: FLUSHALL (if safe in your use case)
# 3. Restart the cluster reshape operationCheck cluster state after BUSYKEY error:
# View cluster status
redis-cli CLUSTER INFO
# Check if any slots are in "migrating" or "importing" state
redis-cli CLUSTER NODES
# If stuck in a state, you may need to issue CLUSTER SETSLOT commandsAdvanced: Manual resolution for stuck slots:
# If a slot is stuck migrating, fix it on source node:
redis-cli -h source-node CLUSTER SETSLOT slot_number NODE node-id
# On destination node:
redis-cli -h dest-node CLUSTER SETSLOT slot_number NODE node-id
# Then retry the reshape
redis-cli --cluster fix cluster-node:6379After resolving the BUSYKEY error and successfully restoring the key, verify the data integrity.
Check key exists and has correct type:
# Check key exists
redis-cli EXISTS mykey
# Check key type matches source
redis-cli TYPE mykey
# Expected output: string, list, set, zset, hash, stream, etc.Verify data content:
# For strings
redis-cli GET mykey
# For lists
redis-cli LRANGE mykey 0 -1
# For sets
redis-cli SMEMBERS mykey
# For hashes
redis-cli HGETALL mykey
# For sorted sets
redis-cli ZRANGE mykey 0 -1 WITHSCORES
# For streams
redis-cli XRANGE mykey - +Compare source and destination (bash script):
#!/bin/bash
SOURCE="source-host:6379"
DEST="destination-host:6379"
KEY="mykey"
echo "Source key info:"
redis-cli -h "$SOURCE" TYPE "$KEY"
redis-cli -h "$SOURCE" STRLEN "$KEY" 2>/dev/null || redis-cli -h "$SOURCE" LLEN "$KEY" 2>/dev/null
echo "Destination key info:"
redis-cli -h "$DEST" TYPE "$KEY"
redis-cli -h "$DEST" STRLEN "$KEY" 2>/dev/null || redis-cli -h "$DEST" LLEN "$KEY" 2>/dev/null
# If types match, data was restored correctlyUnderstanding Redis RESTORE internals:
Redis RESTORE is an atomic operation that deserializes a value previously serialized by DUMP. It's designed to be used primarily for:
1. Replication/backup recovery
2. Key migration between instances
3. Cross-database transfers
The BUSYKEY check exists because RESTORE is meant to be idempotent-resistant - it doesn't automatically overwrite to prevent data loss in scripts or batch operations.
Cluster slot migration and BUSYKEY:
During cluster resharding, Redis nodes migrate slots (and their keys) to other nodes. If a key somehow ends up on both nodes, the BUSYKEY error prevents the cluster from corrupting data. This can happen if:
- A previous resharding was interrupted
- Network failures during migration
- Node crashes mid-transfer
Use CLUSTER FAILOVER or CLUSTER RESET if slots get stuck.
Performance considerations with REPLACE:
Using REPLACE adds a small overhead since Redis must:
1. Check if the key exists
2. If it does, delete it (including all memory cleanup)
3. Then deserialize and store the new value
For bulk operations, this is usually negligible, but if migrating millions of keys, consider:
- Running during low-traffic windows
- Using COPY flag to keep source keys while testing
- Using --cluster-pipeline for bulk cluster imports to batch operations
Preventing BUSYKEY in automation:
When writing scripts to restore keys:
1. Always use REPLACE by default (safer)
2. Log each RESTORE operation
3. Verify data after batch restores
4. Use transactions (MULTI/EXEC) for atomic multi-key restores
Example safe pattern:
local key = KEYS[1]
local serialized = ARGV[1]
-- Always use REPLACE in automated scripts
local result = redis.call('RESTORE', key, 0, serialized, 'REPLACE')
return resultERR 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