How to fix BUSYKEY Target key name already exists in Redis

RedisINTERMEDIATEMEDIUMUpdated Dec 29, 2025· 159 views

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.

Quick fix

Fixes BUSYKEY

redis-cli EXISTS mykey
  1. Check if the key exists at the destination
  2. Use the REPLACE option with RESTORE
  3. Delete the existing key before restore (alternative)
  4. Use MIGRATE with REPLACE for key migration
redis — error
redis-cli EXISTS mykey
BUSYKEY Target key name already exists

What this error means

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.

Typical symptoms

  • RESTORE command fails with 'BUSYKEY Target key name already exists'
  • MIGRATE between Redis instances returns BUSYKEY error
  • Cluster resharding fails with 'Node replied with error: BUSYKEY Target key name already exists'
  • redis-cli --cluster import command fails with BUSYKEY
  • Backup restore operations halt at specific keys
  • Lua scripts using RESTORE fail unexpectedly
  • docker exec redis redis-cli RESTORE returns the error

Common causes

  1. Attempting to RESTORE a key that already exists without the REPLACE option
  2. Running MIGRATE command to a destination that already has the key
  3. Retrying a failed MIGRATE or cluster import without removing the partial/failed key first
  4. Cluster resharding attempting to move a slot to a node that already has some keys from that slot
  5. Multiple restore operations targeting the same key without cleanup
  6. Key not fully deleted from destination before attempting restore

How to fix "BUSYKEY Target key name already exists"

1Check if the key exists at the destination

First, determine whether the key already exists on the target Redis instance.

If you're restoring locally:

bash
redis-cli EXISTS mykey

If the result is (integer) 1, the key exists. If it's (integer) 0, it doesn't exist.

For remote instances:

bash
redis-cli -h target-host -p 6379 EXISTS mykey

If the key exists, you'll need to either delete it or use the REPLACE option in your RESTORE command.

2Use the REPLACE option with RESTORE

The simplest solution is to add the REPLACE option to your RESTORE command, which allows overwriting the existing key.

Syntax with REPLACE:

bash
RESTORE key ttl serialized-value REPLACE

Example - Restoring a string key:

bash
# 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" REPLACE

In Lua scripts:

lua
local serialized = redis.call('DUMP', 'sourcekey')
redis.call('RESTORE', 'targetkey', 0, serialized, 'REPLACE')

With redis-py (Python):

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):

javascript
const redis = require('redis');
const client = redis.createClient();

const serialized = await client.dump('sourcekey');
await client.sendCommand(['RESTORE', 'targetkey', '0', serialized, 'REPLACE']);
3Delete the existing key before restore (alternative)

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:

bash
# 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):

bash
# 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.

4Use MIGRATE with REPLACE for key migration

When migrating keys between Redis instances using MIGRATE, add the REPLACE option to avoid BUSYKEY errors.

MIGRATE syntax with REPLACE:

bash
MIGRATE host port key destination-db timeout REPLACE

Example:

bash
# 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 REPLACE

In a script (migrating all keys matching a pattern):

bash
#!/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
done

With copy flag (keep key in source):

bash
# MIGRATE also supports COPY flag to keep the key in source
redis-cli MIGRATE destination-host 6379 mykey 0 5000 COPY REPLACE
5Fix cluster resharding BUSYKEY errors

If you encounter BUSYKEY during Redis cluster resharding or import, follow these steps:

For redis-cli --cluster import:

bash
# 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-replace

For failed reshard attempts, clean up partial state:

bash
# 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 operation

Check cluster state after BUSYKEY error:

bash
# 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 commands

Advanced: Manual resolution for stuck slots:

bash
# 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:6379
6Verify successful restore with correct data

After resolving the BUSYKEY error and successfully restoring the key, verify the data integrity.

Check key exists and has correct type:

bash
# 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:

bash
# 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):

bash
#!/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 correctly

Advanced notes

Understanding 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:

lua
local key = KEYS[1]
local serialized = ARGV[1]

-- Always use REPLACE in automated scripts
local result = redis.call('RESTORE', key, 0, serialized, 'REPLACE')
return result

Frequently asked questions

What does "BUSYKEY" mean?
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.
How do I fix "BUSYKEY"?
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.
What causes "BUSYKEY"?
Attempting to RESTORE a key that already exists without the REPLACE option Running MIGRATE command to a destination that already has the key Retrying a failed MIGRATE or cluster import without removing the partial/failed key first
Is the "BUSYKEY" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading