ipfs/kubo · error
cp: cannot unlink existing file: %s
Error message
cp: cannot unlink existing file: %s
What it means
`ipfs files cp --force` first unlinks an existing destination entry via unlinkNodeIfExists before placing the new node; this error wraps a failure during that unlink step. It means MFS could not remove the existing entry at dst (see errors 278/279 raised by the helper for the specific causes).
Source
Thrown at core/commands/files.go:585
mkParents, _ := req.Options[filesParentsOptionName].(bool)
if mkParents {
maxDirLinks := int(cfg.Import.UnixFSDirectoryMaxLinks.WithDefault(config.DefaultUnixFSDirectoryMaxLinks))
sizeEstimationMode := cfg.Import.HAMTSizeEstimationMode()
err := ensureContainingDirectoryExists(nd.FilesRoot, dst,
mfs.WithCidBuilder(prefix),
mfs.WithMaxLinks(maxDirLinks),
mfs.WithSizeEstimationMode(sizeEstimationMode),
)
if err != nil {
return err
}
}
force, _ := req.Options[forceOptionName].(bool)
if force {
if err = unlinkNodeIfExists(nd, dst); err != nil {
return fmt.Errorf("cp: cannot unlink existing file: %s", err)
}
}
flush, _ := req.Options[filesFlushOptionName].(bool)
if err := updateNoFlushCounter(nd, flush); err != nil {
return err
}
err = mfs.PutNode(nd.FilesRoot, dst, node)
if err != nil {
return fmt.Errorf("cp: cannot put node in path %s: %s", dst, err)
}
if flush {
if _, err := mfs.FlushPath(req.Context, nd.FilesRoot, dst); err != nil {
return fmt.Errorf("cp: cannot flush the created file %s: %s", dst, err)
}
// Flush parent to clear directory cache and free memory.View on GitHub (pinned to 329838acdf)
Solutions
- Check what exists at dst with `ipfs files stat <dst>`; --force only unlinks existing files, not directories
- Remove directories manually first: `ipfs files rm -r <dst>` then run cp without --force
- Verify every component of the dst path except the last is a directory: `ipfs files ls <parent>`
- Create missing parent directories with `ipfs files mkdir -p <parent>`
Example fix
// before: dst is a directory, cp --force cannot unlink it ipfs files cp --force /ipfs/Qm... /my-dir // error: cp: cannot unlink existing file: not a file: /my-dir // after ipfs files rm -r /my-dir ipfs files cp /ipfs/Qm... /my-dir
Defensive patterns
Strategy: validation
Validate before calling
// ensure parent dirs exist and dst is not a directory before cp --force
run("ipfs", "files", "mkdir", "-p", filepath.Dir(dst))
if statType(dst) == "directory" {
run("ipfs", "files", "rm", "-r", dst)
} Type guard
func isExistingDirectory(dst string) bool {
out, err := run("ipfs", "files", "stat", dst)
return err == nil && strings.Contains(out, "directory")
} Try / catch
if err := ipfsFilesCpForce(src, dst); err != nil {
if strings.Contains(err.Error(), "cannot unlink existing file") {
// inspect dst type; rm -r if directory, then retry
}
} Prevention
- `ipfs files stat <dst>` before using --force
- Remember --force unlinks files only, never directories
- Validate intermediate path components are directories
When it happens
Trigger: Running `ipfs files cp --force <src> <dst>` where dst exists and unlinkNodeIfExists fails — e.g. the dst parent path component is not a directory, the existing child is itself a directory (not a TFile), or the MFS root is in a broken state.
Common situations: Using --force to overwrite a dst that is a directory; dst path contains a file as an intermediate component (`/a.txt/b`); MFS concurrently modified so parent lookup fails.
Related errors
- cp: cannot put node in path %s: %s
- not a file: %s
- %s and %s options are not compatible
- %s: cannot add unnamed files to MFS
- %s: %w
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/e663584ac328d757.
Report an issue: GitHub.