ipfs/kubo · error
cannot remove links from a non-UnixFS dag-pb node; pass --al
Error message
cannot remove links from a non-UnixFS dag-pb node; pass --allow-non-unixfs to skip validation
What it means
RmLink uses dagutils.Editor which operates purely at the dag-pb level; if the node's data is not valid UnixFS at all, the library cannot verify that removing a link keeps metadata consistent, so it refuses. FSNodeFromBytes failed on basePb.Data(), meaning the node is a plain dag-pb node (e.g. created by 'ipfs dag put') not wrapped in UnixFS. --allow-non-unixfs skips this check.
Source
Thrown at core/coreapi/object.go:138
return path.ImmutablePath{}, err
}
baseNd, err := api.core().ResolveNode(ctx, base)
if err != nil {
return path.ImmutablePath{}, err
}
basePb, ok := baseNd.(*dag.ProtoNode)
if !ok {
return path.ImmutablePath{}, dag.ErrNotProtobuf
}
// Same validation as AddLink: dagutils.Editor operates at the dag-pb
// level and cannot update UnixFS metadata (HAMT bitfields, Blocksizes).
if !options.SkipUnixFSValidation {
fsNode, err := ft.FSNodeFromBytes(basePb.Data())
if err != nil {
return path.ImmutablePath{}, fmt.Errorf(
"cannot remove links from a non-UnixFS dag-pb node; " +
"pass --allow-non-unixfs to skip validation")
}
switch fsNode.Type() {
case ft.TDirectory:
// plain directories: safe, no link-count metadata to desync
case ft.THAMTShard:
return path.ImmutablePath{}, fmt.Errorf(
"cannot remove links from a HAMTShard at the dag-pb level " +
"(would corrupt the HAMT bitfield); use 'ipfs files rm' " +
"instead, or pass --allow-non-unixfs to override")
default:
return path.ImmutablePath{}, fmt.Errorf(
"cannot remove links from a UnixFS %s node, "+
"only Directory nodes support link removal at the dag-pb level "+
"(see https://specs.ipfs.tech/unixfs/)",
fsNode.Type())
}View on GitHub (pinned to 329838acdf)
Solutions
- Use 'ipfs dag patch rm-link' (IPLD dag-pb patch) for non-UnixFS dag-pb nodes
- Re-create the node as a UnixFS directory if UnixFS semantics are wanted
- Set --allow-non-unixfs / SkipUnixFSValidation=true to force the edit
Example fix
// before ipfs object patch rm-link <dag-pb-node> oldlink // after ipfs dag patch rm-link <dag-pb-node> -t <node> oldlink
Defensive patterns
Strategy: validation
Validate before calling
if _, err := ft.FSNodeFromBytes(pbNode.Data()); err != nil {
// non-UnixFS dag-pb node: use 'ipfs dag patch' instead of RmLink
} Type guard
func isUnixFSNode(n ipld.Node) bool {
pb, ok := n.(*dagpb.PBNode)
if !ok { return false }
_, err := ft.FSNodeFromBytes(pb.Data())
return err == nil
} Prevention
- Keep dag-pb editing (object/dag patch) separate from UnixFS editing (files API)
- Check node provenance: 'ipfs dag put' nodes are not UnixFS
- Only enable --allow-non-unixfs for deliberate raw dag-pb surgery
When it happens
Trigger: Calling RmLink (object patch rm-link) with SkipUnixFSValidation=false on a node whose protobuf data does not decode to a valid UnixFS FSNode (dag-put-created IPLD nodes, raw dag-pb).
Common situations: Using legacy object patch commands on nodes built with modern 'ipfs dag put' or imported raw dag-pb data; scripts written pre-UnixFS-validation era operating on handcrafted dag-pb.
Related errors
- cannot add named links to a non-UnixFS dag-pb node; pass --a
- cannot add links to a HAMTShard at the dag-pb level (would c
- cannot add named links to a UnixFS %s node, only Directory n
- cannot remove links from a HAMTShard at the dag-pb level (wo
- cannot remove links from a UnixFS %s node, only Directory no
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/8cc099dc57ceaa4f.
Report an issue: GitHub.