Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Redis By James Joyner IV · · 8 min read Last reviewed Jul 2026

Redis Error Guide: 'BUSYKEY Target key name already exists' — Use REPLACE on RESTORE, COPY, and MIGRATE

Quick answer

Fix BUSYKEY Target key name already exists in Redis: understand RESTORE, COPY, and MIGRATE overwrite behavior and add REPLACE to make migrations idempotent.

  • #redis
  • #database
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this Redis error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

Redis returns BUSYKEY when a command that creates a key at a specific name finds that the name is already occupied and you did not tell it to overwrite. It is raised by RESTORE (deserializing a DUMP payload), COPY (duplicating a key), and MIGRATE (moving keys to another instance) whenever the destination key already exists and no REPLACE option was given.

The literal error clients receive:

(error) BUSYKEY Target key name already exists

This is a safety default, not a failure: these commands refuse to clobber existing data unless you explicitly opt in with REPLACE. It most often appears when a migration or import is retried — the first run created the key, and the retry hits the key it just wrote.

Symptoms

  • RESTORE, COPY, or MIGRATE fails with BUSYKEY for keys that already exist on the destination.
  • A migration or restore that is re-run (after a partial failure) fails on exactly the keys the first pass wrote.
  • Manual DUMP/RESTORE round-trips fail on the second attempt.
redis-cli RESTORE user:42 0 "$PAYLOAD"
(error) BUSYKEY Target key name already exists
redis-cli EXISTS user:42
(integer) 1

Common Root Causes

1. RESTORE onto an existing key without REPLACE

The destination already holds user:42, and RESTORE refuses to overwrite it.

redis-cli TYPE user:42
hash

2. A retried or resumed migration

A migration script partially succeeded, then re-ran from the start; every key the first pass created now trips BUSYKEY.

3. COPY to an occupied destination

redis-cli COPY cart:src cart:dst
(error) BUSYKEY Target key name already exists

4. MIGRATE where the key exists on the target

Moving a key that was already moved (or exists independently) on the destination instance.

redis-cli MIGRATE dst 6379 order:9 0 5000
(error) BUSYKEY Target key name already exists

Diagnostic Workflow

Step 1: Confirm the key already exists and its type

redis-cli EXISTS user:42
redis-cli TYPE user:42
redis-cli TTL user:42

If EXISTS returns 1, BUSYKEY is expected without REPLACE.

Step 2: Decide whether overwriting is safe

Compare the existing value with what you are about to write. On a migration retry it is usually the same data; for an import into a shared namespace it may not be.

redis-cli MEMORY USAGE user:42
redis-cli OBJECT ENCODING user:42

Step 3: For MIGRATE, check both ends

# Source
redis-cli -h SRC EXISTS order:9
# Destination
redis-cli -h DST EXISTS order:9

Step 4: Verify your DUMP payload matches the target version

A RESTORE from an incompatible or truncated DUMP can fail differently (DUMP payload version or checksum are wrong); BUSYKEY specifically means the payload is fine but the name is taken.

redis-cli -h SRC DUMP order:9 | wc -c   # non-empty payload

Step 5: Read the migration logs

sudo journalctl -u redis-server --no-pager | grep -iE 'BUSYKEY|RESTORE|MIGRATE' | tail

Example Root Cause Analysis

A cross-datacenter migration script iterates keys with SCAN and moves each with DUMP/RESTORE. It crashes at 60% through a batch and is restarted from the beginning. Immediately it floods with BUSYKEY Target key name already exists on every key in the first 60%.

The cause is clear: the destination already holds the keys the first run wrote, and the RESTORE call was written without REPLACE, so re-running is not idempotent:

redis-cli -h DST EXISTS user:42     # (integer) 1  — written by the first pass

The fix is to make the migration idempotent by adding REPLACE, which overwrites the destination key with the fresh payload (and its TTL) instead of erroring:

TTL=$(redis-cli -h SRC PTTL user:42)
redis-cli -h SRC DUMP user:42 | \
  redis-cli -h DST -x RESTORE user:42 "$TTL" REPLACE   # OK — overwrites

Because REPLACE makes each step safe to repeat, the script can now be re-run end-to-end after any crash without hitting BUSYKEY. The team verified TYPE/TTL on the destination before deleting the source.

Prevention Best Practices

  • Add REPLACE to RESTORE, COPY, and MIGRATE in any migration or import that must be safely re-runnable — idempotency is the goal.
  • Preserve TTLs explicitly: pass the source PTTL to RESTORE so overwritten keys keep their expiry.
  • Before overwriting in a shared namespace, confirm you are not clobbering a different owner’s data — REPLACE is unconditional.
  • Checkpoint migration progress so a resume skips already-moved keys instead of relying on BUSYKEY as flow control.
  • For cluster moves, remember MIGRATE ... COPY REPLACE keeps the source and overwrites the target — choose the flags deliberately.
  • Feed migration errors into the free incident assistant, and browse more Redis guides.

Quick Command Reference

# Confirm the destination key exists
redis-cli EXISTS user:42
redis-cli TYPE user:42

# Idempotent restore that preserves TTL and overwrites
TTL=$(redis-cli -h SRC PTTL user:42)
redis-cli -h SRC DUMP user:42 | redis-cli -h DST -x RESTORE user:42 "$TTL" REPLACE

# Overwrite-safe copy and migrate
redis-cli COPY cart:src cart:dst REPLACE
redis-cli MIGRATE dst 6379 order:9 0 5000 COPY REPLACE

Conclusion

BUSYKEY Target key name already exists means a RESTORE, COPY, or MIGRATE found the destination name occupied and refused to overwrite it. The typical root causes are:

  1. RESTORE onto an existing key without REPLACE.
  2. A retried or resumed migration re-writing keys the first pass created.
  3. COPY/MIGRATE to a destination that already holds the key.

The fix is almost always to add REPLACE so the operation is idempotent — but only after confirming you are not clobbering data a different owner cares about, and remembering to carry the TTL across so overwritten keys keep their expiry.

Free download · 368-page PDF

Fixed it? Get 500 Redis & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.