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
- Retry the operation — a lost race with a concurrent delete/rename is typically transient; the transaction rolls back safely.
- Check whether another process is deleting/renaming the same path concurrently and serialize at the application level if needed.
- Run `juicefs fsck <meta-url>` to verify metadata consistency if the error repeats on a quiet volume.
- 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
- Avoid multiple clients renaming/unlinking the same path concurrently.
- Never manipulate jfs_edge rows outside JuiceFS tooling.
- Leave DB transaction isolation at the engine default.
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
- get session ID: %s
- insert new session %d: %s
- find sustained %d: %s
- failed to clean up sid %d
- only %d records inserted
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/65ced7660ace3a1b.
Report an issue: GitHub.