ipfs/kubo · error

expected a file handle

Error message

expected a file handle

What it means

`ipfs dag import` iterates req.Files entries and each entry must be a readable file handle (files.File). If an entry cannot be converted to a file — e.g. a directory entry, null entry, or a nonexistent stdin/pipe — the command aborts with "expected a file handle".

Source

Thrown at core/commands/dag/import.go:119

	var blockCount, blockBytesCount uint64

	// remember last valid block and provide a meaningful error message
	// when a truncated/mangled CAR is being imported
	importError := func(previous blocks.Block, current blocks.Block, err error) error {
		if current != nil {
			return fmt.Errorf("import failed at block %q: %w", current.Cid(), err)
		}
		if previous != nil {
			return fmt.Errorf("import failed after block %q: %w", previous.Cid(), err)
		}
		return fmt.Errorf("import failed: %w", err)
	}

	it := req.Files.Entries()
	for it.Next() {
		file := files.FileFromEntry(it)
		if file == nil {
			return errors.New("expected a file handle")
		}

		// import blocks
		err = func() error {
			// wrap a defer-closer-scope
			//
			// every single file in it() is already open before we start
			// just close here sooner rather than later for neatness
			// and to surface potential errors writing on closed fifos
			// this won't/can't help with not running out of handles
			defer file.Close()

			var previous blocks.Block

			// Wrap the file to hide the io.Seeker interface.
			// Over the HTTP API the underlying reader is a multipart stream
			// that cannot seek, but boxo's ReaderFile advertises io.Seeker
			// anyway and returns ErrNotSupported at runtime. Hiding the

View on GitHub (pinned to 329838acdf)

Solutions

  1. Pass actual .car files, not directories: `ipfs dag import dir/*.car`
  2. Verify the file exists and is readable before importing
  3. For the HTTP API, ensure the multipart body contains a proper file part

Example fix

// before
ipfs dag import ./car-dir
// error: expected a file handle
// after
ipfs dag import ./car-dir/*.car
Defensive patterns

Strategy: validation

Validate before calling

// ensure each argument is a regular readable file
for _, p := range carPaths {
    st, err := os.Stat(p)
    if err != nil || st.IsDir() {
        return fmt.Errorf("%s is not a file", p)
    }
}

Prevention

When it happens

Trigger: Calling `ipfs dag import` with a directory instead of .car files; passing a named pipe/stdin entry that is not a regular stream; programmatic use of the RPC API with malformed multipart file entries.

Common situations: Shell glob expanding to directories; HTTP API multipart body missing the file part; using --stdin-name incorrectly.

Related errors


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