juicedata/juicefs · error

database %s://%s is not empty

Error message

database %s://%s is not empty

What it means

JuiceFS's `load` (metadata restore) refuses to write into a TKV (etcd/TiKV/etc.) database that already contains data. After scanning for existing keys in the target metadata engine, `prepareLoad` returns this error to protect an existing volume's metadata from being overwritten or merged by a partial load.

Source

Thrown at pkg/meta/tkv_bak.go:86

}

func (m *kvMeta) load(ctx Context, typ int, opt *LoadOption, val proto.Message) error {
	return errors.New("not implemented, use kvMeta.LoadMetaV2 instead")
}

func (m *kvMeta) prepareLoad(ctx Context, opt *LoadOption) error {
	opt.check()

	var exist bool
	err := m.txn(ctx, func(tx *kvTxn) error {
		exist = tx.exist(m.fmtKey())
		return nil
	})
	if err != nil {
		return err
	}
	if exist {
		return fmt.Errorf("database %s://%s is not empty", m.Name(), m.addr)
	}
	return nil
}

func printSums(sums map[int]*atomic.Uint64) string {
	var p string
	for typ, sum := range sums {
		p += fmt.Sprintf("%d num: %d\n", typ, sum.Load())
	}
	return p
}

func (m *kvMeta) dumpCounters(ctx Context, opt *DumpOption, ch chan<- *dumpedResult) error {
	return m.txn(ctx, func(tx *kvTxn) error {
		counters := make([]*pb.Counter, 0, len(counterNames)+1)
		if m.getFormat().ChangeLog {
			maxKey := m.findLastLogKey(tx)
			if maxKey > 0 {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Verify you are loading into the intended (empty) metadata URL; check the address and prefix
  2. Inspect the target DB and delete existing keys of that volume (e.g. FLUSHDB for a dedicated Redis, drop the schema/table for SQL, delete the etcd prefix) only if the data is disposable
  3. Restore into a fresh database/instance and remount clients with the new URL
  4. If a previous load left partial data, remove its keys before retrying

Example fix

// before
$ juicefs load redis://old-host/1 dump.bin
FATAL: database redis://old-host:6379/1 is not empty
// after
$ redis-cli -h old-host -n 1 FLUSHDB   # only if data is disposable
$ juicefs load redis://old-host/1 dump.bin
Defensive patterns

Strategy: validation

Validate before calling

// Check the target DB is empty before loading (etcd example)
out, err := clientv3.New(clientv3.Config{Endpoints: []string{"host:2379"}}).Get(ctx, "", clientv3.WithPrefix(), clientv3.WithKeysOnly(), clientv3.WithCountOnly())
if err != nil { log.Fatal(err) }
if out.Count > 0 { log.Fatal("target metadata DB is not empty; choose an empty DB or clear it first") }

Prevention

When it happens

Trigger: Running `juicefs load` (or restore from backup) against a metadata URL whose database already has keys — e.g. a volume was formatted or mounted before, or a previous load partially completed and left data behind.

Common situations: Pointing `load` at a live volume's metadata instead of an empty DB; reusing a Redis/SQL/etcd instance that hosts other volumes; retrying a failed load without clearing the destination; wrong `--prefix` so leftover keys from another logical volume are detected.

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/0c5fb31ceb010e3d. Report an issue: GitHub.