ipfs/kubo · error

%s: MFS destination is a file: only one entry can be copied

Error message

%s: MFS destination is a file: only one entry can be copied to %q

What it means

When adding multiple files with --to-files pointing at a file destination (no trailing slash), only one entry may be linked into MFS. The command tracks whether a file has already been placed (fileAddedToMFS); a second entry targeting the same file path would overwrite it, so it aborts. This protects against silently replacing the first MFS link with the second.

Source

Thrown at core/commands/add.go:609

					if dstAsDir {
						mfsNode, err := mfs.Lookup(ipfsNode.FilesRoot, toFilesDst)
						// confirm dst exists
						if err != nil {
							errCh <- fmt.Errorf("%s: MFS destination directory %q does not exist: %w", toFilesOptionName, toFilesDst, err)
							return
						}
						// confirm dst is a dir
						if mfsNode.Type() != mfs.TDir {
							errCh <- fmt.Errorf("%s: MFS destination %q is not a directory", toFilesOptionName, toFilesDst)
							return
						}
						// if MFS destination is a dir, append filename to the dir path
						toFilesDst += gopath.Base(addit.Name())
					}

					// error if we try to overwrite a preexisting file destination
					if fileAddedToMFS && !dstAsDir {
						errCh <- fmt.Errorf("%s: MFS destination is a file: only one entry can be copied to %q", toFilesOptionName, toFilesDst)
						return
					}

					_, err = mfs.Lookup(ipfsNode.FilesRoot, gopath.Dir(toFilesDst))
					if err != nil {
						errCh <- fmt.Errorf("%s: MFS destination parent %q %q does not exist: %w", toFilesOptionName, toFilesDst, gopath.Dir(toFilesDst), err)
						return
					}

					var nodeAdded ipld.Node
					nodeAdded, err = api.Dag().Get(req.Context, pathAdded.RootCid())
					if err != nil {
						errCh <- err
						return
					}
					err = mfs.PutNode(ipfsNode.FilesRoot, toFilesDst, nodeAdded)
					if err != nil {
						errCh <- fmt.Errorf("%s: cannot put node in path %q: %w", toFilesOptionName, toFilesDst, err)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Use a directory destination with a trailing slash, e.g. --to-files /dir/, so each entry is placed under its own name
  2. Split into separate `ipfs add --to-files` invocations, one per destination file
  3. Check argument count / recursive flag before running when --to-files targets a file

Example fix

// before
ipfs add -r --to-files /out.bin ./mydir
// after
ipfs add -r --to-files /out/ ./mydir   # trailing slash: per-entry names under /out/
Defensive patterns

Strategy: validation

Validate before calling

// ensure a file-destination add receives exactly one entry
count=$(find src -type f | wc -l)
if [ "$count" -gt 1 ]; then dst="/out/"; else dst="/out.bin"; fi
ipfs add --to-files "$dst" $(find src -type f)

Prevention

When it happens

Trigger: Run `ipfs add --to-files /out.bin fileA fileB` (or `ipfs add -r --to-files /out.bin dir/`): the first entry links to /out.bin, the second entry hits fileAddedToMFS && !dstAsDir and errors with 'MFS destination is a file: only one entry can be copied to /out.bin'.

Common situations: Users add a directory recursively while --to-files points at a single file; users pass multiple file arguments expecting concatenation into one MFS path; batch scripts that reuse one --to-files target for several adds in one invocation.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/66610c77f4d5a6a3. Report an issue: GitHub.