ipfs/kubo · error

unknown file type

Error message

unknown file type

What it means

Adder's node dispatcher handles the concrete files.Node kinds it supports: directories (addDir), symlinks (addSymlink), and files (addFile). Any files.Node that implements the interface but matches none of these concrete types falls to the default branch, which fails with 'unknown file type'. It guards the importer against being handed node kinds coreunix cannot serialize into UnixFS.

Source

Thrown at core/coreunix/add.go:431

			return err
		}
		if err := mr.FlushMemFree(adder.ctx); err != nil {
			return err
		}

		adder.liveNodes = 0
	}
	adder.liveNodes++

	switch f := file.(type) {
	case files.Directory:
		return adder.addDir(ctx, path, f, toplevel)
	case *files.Symlink:
		return adder.addSymlink(ctx, path, f)
	case files.File:
		return adder.addFile(path, f)
	default:
		return errors.New("unknown file type")
	}
}

func (adder *Adder) addSymlink(ctx context.Context, path string, l *files.Symlink) error {
	sdata, err := unixfs.SymlinkData(l.Target)
	if err != nil {
		return err
	}

	if !adder.FileMtime.IsZero() {
		fsn, err := unixfs.FSNodeFromBytes(sdata)
		if err != nil {
			return err
		}

		fsn.SetModTime(adder.FileMtime)
		if sdata, err = fsn.GetBytes(); err != nil {
			return err

View on GitHub (pinned to 329838acdf)

Solutions

  1. Convert unsupported node types to files.File (bytes) or files.Directory (map/slice) before importing
  2. Ensure all files types come from one import path consistent with the kubo version in use
  3. Upgrade coreunix/go-libipfs if a newly supported files kind (e.g. a new special node) is required
  4. Log/debug the concrete type of the offending node (fmt.Sprintf("%T")) and implement a wrapper exposing it as a supported kind

Example fix

// before: custom node type
type dirNode struct{ files.Node }
adder.AddAllAndPin(ctx, dirNode{}, false) // unknown file type
// after: map it to a known kind
entries := map[string]files.Node{"a.txt": files.NewBytesFile([]byte("a"))}
root := files.NewMapFile("", "", entries)
adder.AddAllAndPin(ctx, root, false)
Defensive patterns

Strategy: type-guard

Validate before calling

switch n.(type) {
case files.File, *files.Symlink, files.Directory:
	// ok
default:
	return fmt.Errorf("cannot import node of type %T", n)
}

Type guard

func isAddable(n files.Node) bool {
	switch n.(type) {
	case files.File, *files.Symlink, files.Directory:
		return true
	default:
		return false
	}
}

Try / catch

if err := adder.AddAllAndPin(ctx, node, false); err != nil {
	if err.Error() == "unknown file type" {
		return fmt.Errorf("node %T must be converted to File/Directory/Symlink", node)
	}
	return err
}

Prevention

When it happens

Trigger: Calling AddAllAndPin / Add with a files.Node implementation that is none of *files.Symlink, files.File, or files.Directory (note files.File is a value type here, so non-pointer or custom File implementations matching the interface are handled, but novel custom kinds are not).

Common situations: Custom files.Node types from application code; type mismatches from mixing go-ipfs-files and go-libipfs/files packages so the type switch misses; passing a files.Directory stored in an interface the switch does not reach (nil or wrapper types).

Related errors


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