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 theView on GitHub (pinned to 329838acdf)
Solutions
- Pass actual .car files, not directories: `ipfs dag import dir/*.car`
- Verify the file exists and is readable before importing
- 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
- Glob with *.car, not directory names
- Check existence/readability before invoking
- For RPC clients, send each CAR as a file part
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
- --%s implies --%s=false and cannot be combined with --%s=tru
- expected a regular file
- supernode routing was never fully implemented and has been r
- unrecognized routing option: %s
- invalid configuration profile: %s
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/67c3da898d878ed5.
Report an issue: GitHub.