ipfs/kubo · error
cannot add links to a HAMTShard at the dag-pb level (would c
Error message
cannot add links to a HAMTShard at the dag-pb level (would corrupt the HAMT bitfield); use 'ipfs files' commands instead, or pass --allow-non-unixfs to override
What it means
CoreAPI's AddLink edits dag-pb nodes directly, which is only safe for plain UnixFS directories. A HAMTShard (a hamt-shard directory created e.g. with --hamt-encoding) stores membership in a bitfield spread across its DAG; blind dag-pb link insertion would desync it and silently corrupt lookups. The library refuses and points to the 'ipfs files' API or the --allow-non-unixfs escape hatch.
Source
Thrown at core/coreapi/object.go:78
// This command operates at the dag-pb level via dagutils.Editor, which
// only manipulates ProtoNode links without updating UnixFS metadata.
// Only plain UnixFS Directory nodes are safe to mutate this way.
// File nodes: adding links corrupts Blocksizes, content lost on read-back.
// HAMTShard nodes: bitfield not updated, shard trie becomes inconsistent.
// https://specs.ipfs.tech/unixfs/#pbnode-links-name
// https://github.com/ipfs/kubo/issues/7190
if !options.SkipUnixFSValidation {
fsNode, err := ft.FSNodeFromBytes(basePb.Data())
if err != nil {
return path.ImmutablePath{}, fmt.Errorf(
"cannot add named links to 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 add links to a HAMTShard at the dag-pb level " +
"(would corrupt the HAMT bitfield); use 'ipfs files' " +
"commands instead, or pass --allow-non-unixfs to override")
default:
return path.ImmutablePath{}, fmt.Errorf(
"cannot add named links to a UnixFS %s node, "+
"only Directory nodes support link addition at the dag-pb level "+
"(see https://specs.ipfs.tech/unixfs/)",
fsNode.Type())
}
}
var createfunc func() *dag.ProtoNode
if options.Create {
createfunc = ft.EmptyDirNode
}
e := dagutils.NewDagEditor(basePb, api.dag)View on GitHub (pinned to 329838acdf)
Solutions
- Use the MFS/files API (coreapi FilesAPI) to modify the directory, or CLI 'ipfs files' commands
- Re-create the directory as a plain UnixFS directory if dag-pb patching is truly required
- Set the --allow-non-unixfs option / SkipUnixFSValidation=true only if you accept corrupting the HAMT bitfield
Example fix
// before (RPC) ipfs object patch add-link <hamt-dir-cid> child.txt <child-cid> // after ipfs files cp /ipfs/<child-cid> /my-hamt-dir/child.txt
Defensive patterns
Strategy: validation
Validate before calling
fsNode, err := ft.FSNodeFromBytes(pbNode.Data())
if err == nil && fsNode.Type() == ft.THAMTShard {
// route through files/MFS API instead of AddLink
} Type guard
func isHAMTShard(n ipld.Node) bool {
pb, ok := n.(*dagpb.PBNode)
if !ok { return false }
fsn, err := ft.FSNodeFromBytes(pb.Data())
return err == nil && fsNode.Type() == ft.THAMTShard
} Prevention
- Use MFS ('ipfs files') for any directory mutation instead of legacy object patch
- Check directory type (is-sharded via 'ipfs files stat') before patching
- Treat object patch commands as dag-pb-level and UnixFS-plain-directory only
When it happens
Trigger: Calling PinAPI-adjacent object API AddLink (coreapi/unixfs AddLink) with SkipUnixFSValidation=false on a path whose root node is a UnixFS HAMTShard (fs.Type()==THAMTShard).
Common situations: Directories created with 'ipfs add --json' or 'ipfs files --hamt-encoding' become HAMT sharded; scripts that worked on plain directories using the deprecated object/patch add-link RPC start failing after re-sharding the directory.
Related errors
- cannot remove links from a HAMTShard at the dag-pb level (wo
- cannot add named links to a UnixFS %s node, only Directory n
- cannot remove links from a non-UnixFS dag-pb node; pass --al
- cannot remove links from a UnixFS %s node, only Directory no
- unexpected Objects len
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/176e39feaaeccbcc.
Report an issue: GitHub.