juicedata/juicefs · error

delete src failed

Error message

delete src failed

What it means

Thrown inside dbMeta.Rename's transaction when deleting the source `edge` row (the directory entry being renamed) deletes 0 or more than 1 rows instead of exactly 1. Just before this, the code re-read the edge within the same transaction, so a count != 1 means the entry vanished or is inconsistent between the read and the delete — an internal consistency guard, not a user-facing SQL error.

Source

Thrown at pkg/meta/sql.go:2527

			*tInode = dino
			m.parseAttr(&dn, tAttr)
		}

		if exchange {
			if _, err := s.Cols("inode", "type").Update(&de, &edge{Parent: parentSrc, Name: se.Name}); err != nil {
				return err
			}
			if _, err := s.Cols("inode", "type").Update(&se, &edge{Parent: parentDst, Name: de.Name}); err != nil {
				return err
			}
			if _, err := s.Cols("ctime", "ctimensec", "parent").Update(dn, &node{Inode: dino}); err != nil {
				return err
			}
		} else {
			if n, err := s.Delete(&edge{Parent: parentSrc, Name: se.Name}); err != nil {
				return err
			} else if n != 1 {
				return fmt.Errorf("delete src failed")
			}
			if dino > 0 {
				if trash > 0 {
					newSpace, newInode = align4K(0), 1
					if de.Type == TypeFile {
						newSpace = align4K(dn.Length)
					}
					if _, err := s.Cols("ctime", "ctimensec", "parent").Update(dn, &node{Inode: dino}); err != nil {
						return err
					}
					name := m.trashEntry(parentDst, dino, string(de.Name))
					if err = mustInsert(s, &edge{Parent: trash, Name: []byte(name), Inode: dino, Type: de.Type}); err != nil {
						return err
					}
				} else if de.Type != TypeDirectory && dn.Nlink > 0 {
					if _, err := s.Cols("ctime", "ctimensec", "nlink", "parent").Update(dn, &node{Inode: dino}); err != nil {
						return err
					}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Retry the operation — a lost race with a concurrent delete/rename is typically transient; the transaction rolls back safely.
  2. Check whether another process is deleting/renaming the same path concurrently and serialize at the application level if needed.
  3. Run `juicefs fsck <meta-url>` to verify metadata consistency if the error repeats on a quiet volume.
  4. Confirm the database's transaction isolation is at the engine default (REPEATABLE READ/READ COMMITTED).

Example fix

// before: two clients rename/unlink src simultaneously -> one gets "delete src failed"
// after: handle the race by retrying the failed rename
err := m.Rename(ctx, parentSrc, nameSrc, parentDst, nameDst)
if err != nil && strings.Contains(err.Error(), "delete src failed") {
    err = m.Rename(ctx, parentSrc, nameSrc, parentDst, nameDst) // re-check ENOENT path first
}
Defensive patterns

Strategy: retry

Validate before calling

// check the source entry still exists before renaming
if _, err := os.Stat(srcPath); os.IsNotExist(err) {
    return nil // nothing to rename; skip instead of racing
}

Try / catch

err := fs.Rename(ctx, src, dst)
if err != nil && strings.Contains(err.Error(), "delete src failed") {
    if _, statErr := fs.Stat(src); statErr != nil {
        return nil // src really vanished — concurrent delete won the race
    }
    err = fs.Rename(ctx, src, dst) // transient race; retry once
}

Prevention

When it happens

Trigger: A concurrent rename/unlink of the same source name racing between the in-transaction edge re-read and the DELETE; metadata row manipulation outside JuiceFS; SQL engines with weak isolation (READ UNCOMMITTED / non-transactional DDL interference).

Common situations: Multiple clients renaming/deleting the same file path simultaneously; a data-recovery tool or manual DELETE touching jfs_edge mid-rename; running the volume on a database with the transaction isolation lowered from the default.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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