ipfs/kubo · error
unrecognized fsn type: %#v
Error message
unrecognized fsn type: %#v
What it means
Adder's output handling dispatches on the type of an fsn (filesystem node) entry collected during a UnixFS add operation. When outputDirs/outputDagnode encounters an fsn value whose concrete type is neither a directory nor a recognized node kind, it fails with this error including the value formatted with %#v. It indicates an internal dispatch gap: a files.Node implementation that coreunix does not know how to serialize.
Source
Thrown at core/coreunix/add.go:265
return err
}
childpath := gopath.Join(path, name)
err = adder.outputDirs(childpath, child)
if err != nil {
return err
}
fsn.Uncache(name)
}
nd, err := fsn.GetNode()
if err != nil {
return err
}
return outputDagnode(adder.Out, path, nd)
default:
return fmt.Errorf("unrecognized fsn type: %#v", fsn)
}
}
func (adder *Adder) addNode(node ipld.Node, path string) error {
// patch it into the root
if path == "" {
path = node.Cid().String()
}
if pi, ok := node.(*posinfo.FilestoreNode); ok {
node = pi.Node
}
mr, err := adder.mfsRoot()
if err != nil {
return err
}
View on GitHub (pinned to 329838acdf)
Solutions
- Pass only standard files types: files.NewBytesFile, files.NewMapFile, files.NewSliceFile, files.NewSerialFile, files.NewSymlinkFile
- Check that all files imports come from a single consistent package path (matching the kubo go-libipfs/files version)
- Update kubo/coreunix and go-libipfs to compatible versions so type switches recognize your node types
- If you truly need custom node kinds, convert them to a supported type (directory map, slice, or file) before adding
Example fix
// before: custom node unknown to the switch
type myNode struct{ files.Node }
adder.AddAllAndPin(ctx, myNode{}...) // unrecognized fsn type
// after: convert to a supported type
entry, _ := files.NewBytesFile(data)
iter := files.NewSliceFile("", "", []files.Node{entry})
adder.AddAllAndPin(ctx, iter, false) Defensive patterns
Strategy: type-guard
Validate before calling
switch n.(type) {
case files.File, *files.Symlink, files.Directory:
// ok
default:
return fmt.Errorf("unsupported node type %T", n)
} Type guard
func isKnownFsn(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 strings.Contains(err.Error(), "unrecognized fsn type") {
return fmt.Errorf("convert node %T to a supported files kind", node)
}
return err
} Prevention
- Only build inputs with files.NewBytesFile/NewMapFile/NewSliceFile/NewSerialFile/NewSymlinkFile
- Use a single consistent go-libipfs/files import path
- When wrapping files.Node, unwrap to the underlying supported type before adding
- Pin go-libipfs and kubo versions together
When it happens
Trigger: Calling Adder.AddAllAndPin / Add with an files.Node implementation that is not files.File, files.Directory, or files.Symlink (e.g. a custom files.Node type implementing the interface but not one of the known concrete kinds), typically via files.NewMapFile or a wrapped custom node.
Common situations: Custom importer code wrapping or substituting files.Node types; passing a files.Node whose concrete type changed after a go-ipfs-files library version upgrade; mixing old import paths (github.com/ipfs/go-ipfs/files vs github.com/ipfs/go-libipfs/files) so type switches no longer match.
Related errors
- expected at least one child dir, got none
- unknown file type
- unknown layout: %d
- unsupported file type '%s'
- file type %d not supported
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/40b426f909bac04d.
Report an issue: GitHub.