juicedata/juicefs · error

found key with same prefix: %s

Error message

found key with same prefix: %s

What it means

Before restoring metadata (prepareLoad), JuiceFS verifies the target is empty. With a Redis ClusterClient it cannot just check DBSize (per-node), so it scans for any keys sharing the volume's prefix; any found key aborts the load with this error naming the offending key.

Source

Thrown at pkg/meta/redis_bak.go:984

func (m *redisMeta) loadParents(ctx Context, msg proto.Message) error {
	pipe := m.rdb.Pipeline()
	for _, p := range msg.(*pb.Batch).Parents {
		pipe.HIncrBy(ctx, m.parentKey(Ino(p.Inode)), Ino(p.Parent).String(), p.Cnt)
		if pipe.Len() >= redisPipeLimit {
			if err := execPipe(ctx, pipe); err != nil {
				return err
			}
		}
	}
	return execPipe(ctx, pipe)
}

func (m *redisMeta) prepareLoad(ctx Context, opt *LoadOption) error {
	opt.check()
	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)
		}
	}
	return nil
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Flush the stale keys: run `redis-cli --cluster` FLUSHALL on the target cluster, or delete keys matching the reported prefix.
  2. Point the load at the correct (empty) Redis cluster address.
  3. If a previous load partially failed, clear the prefix and retry the load.
  4. For non-cluster Redis, DBSize is used instead — verify you are actually connecting to a cluster and whether that is intended.

Example fix

// before
juicefs load -i backup.json redis://stale-cluster:6379/myfs
// after
redis-cli -c -h stale-cluster FLUSHALL
juicefs load -i backup.json redis://stale-cluster:6379/myfs
Defensive patterns

Strategy: validation

Validate before calling

// pre-check before load (cluster)
var found bool
rdb.ForEachMaster(ctx, func(ctx context.Context, c *redis.Client) error {
    return c.Scan(ctx, 0, "*", 100).Iterator().NextErr == nil && !found && func() error {
        keys, _ := c.Scan(ctx, 0, "*", 10).Result()
        if len(keys) > 0 { found = true }
        return nil
    }()
})
if found { return errors.New("cluster not empty, aborting load") }

Try / catch

if err := load(ctx, meta, f); err != nil {
    if strings.Contains(err.Error(), "found key with same prefix") {
        log.Fatalf("target cluster holds another volume's keys: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Running `juicefs load` (or warmup restore) into a Redis Cluster that already contains keys under the same prefix — typically a previous volume using the same cluster, or loading into the wrong cluster address.

Common situations: Loading a backup into a cluster that still holds an old volume's data; pointing --meta at a shared production cluster instead of a fresh one; a prior failed load that partially wrote keys before aborting.

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/0925d8d2f73ae979. Report an issue: GitHub.