juicedata/juicefs · error

found key with same prefix: %s

Error message

found key with same prefix: %s

What it means

Returned by LoadMeta (redis.go:5186) when loading a metadata dump into a Redis Cluster: a SCAN finds at least one existing key under the target prefix, meaning the cluster DB is not empty and loading would overwrite or collide with existing data. LoadMeta requires an empty destination, so it aborts with the first colliding key.

Source

Thrown at pkg/meta/redis.go:5186

		xattrs := make(map[string]interface{})
		for _, x := range e.Xattrs {
			xattrs[x.Name] = unescape(x.Value)
		}
		p.HSet(ctx, m.xattrKey(inode), xattrs)
	}

	attr.AccessACL = m.saveACL(loadACL(e.AccessACL), aclMaxId)
	attr.DefaultACL = m.saveACL(loadACL(e.DefaultACL), aclMaxId)

	p.Set(ctx, m.inodeKey(inode), m.marshal(attr), 0)
	tryExec()
}

func (m *redisMeta) LoadMeta(r io.Reader) (err error) {
	ctx := Background()
	if _, ok := m.rdb.(*redis.ClusterClient); ok {
		err = m.scan(ctx, "*", func(keys []string) error {
			return fmt.Errorf("found key with same prefix: %s", keys[0])
		})
		if err != nil {
			return err
		}
	} else {
		dbsize, err := m.rdb.DBSize(ctx).Result()
		if err != nil {
			return err
		}
		if dbsize > 0 {
			return fmt.Errorf("Database redis://%s is not empty", m.addr)
		}
	}

	p := m.rdb.TxPipeline()
	tryExec := func() {
		if p.Len() > 1000 {
			if rs, err := p.Exec(ctx); err != nil {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Point the load at an empty Redis cluster/database (fresh instance or new prefix).
  2. If the existing data is unwanted, flush the keys (FLUSHDB / FLUSHALL, or delete keys under the prefix) and re-run the load.
  3. Load into a different logical DB or use a distinct prefix if sharing a Redis instance.
  4. Double-check the target URL in the command — a typo may have aimed the restore at the wrong cluster.

Example fix

// before
juicefs load redis-cluster://prod:6379/0 backup.json
// after: use an empty destination
juicefs load redis-cluster://restore:6379/0 backup.json
Defensive patterns

Strategy: validation

Validate before calling

// shell: ensure the target cluster is empty before loading
keys=$(redis-cli -c -h restore -p 6379 --scan --count 1000 | head -1)
[ -z "$keys" ] || { echo "target not empty"; exit 1; }

Try / catch

if err := meta.LoadMeta(ctx, r); err != nil {
    if strings.Contains(err.Error(), "found key with same prefix") {
        // choose an empty cluster or flush the prefix, then retry
    }
    return err
}

Prevention

When it happens

Trigger: Running `juicefs load` (metadata restore) against a Redis Cluster whose keyspace already contains keys with the configured prefix; re-running a load into a cluster that was already loaded once.

Common situations: Restoring a backup over an existing volume; accidental load into a production Redis cluster; double-executing a restore script.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/2218b008b5f13af0. Report an issue: GitHub.