ipfs/kubo · error
cannot add named links to a non-UnixFS dag-pb node; pass --a
Error message
cannot add named links to a non-UnixFS dag-pb node; pass --allow-non-unixfs to skip validation
What it means
ObjectAPI.AddLink links by name into a dag-pb node, but named links are only safe on UnixFS nodes (directory/hash metadata must stay consistent). When the target node's data cannot be parsed as a UnixFS node, the API refuses to edit it and suggests the --allow-non-unixfs escape hatch, which skips validation (with known HAMT-shard consistency risks, see issue 7190).
Source
Thrown at core/coreapi/object.go:70
return path.ImmutablePath{}, err
}
basePb, ok := baseNd.(*dag.ProtoNode)
if !ok {
return path.ImmutablePath{}, dag.ErrNotProtobuf
}
// 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())
}View on GitHub (pinned to 329838acdf)
Solutions
- Verify the target CID is a UnixFS directory (created via `ipfs add` or MFS), not a raw dag-pb node.
- Inspect with `ipfs dag get <cid>` or `ipfs files stat` to confirm the node type.
- If you explicitly need to edit a non-UnixFS dag-pb node, pass --allow-non-unixfs (SkipUnixFSValidation=true) and accept the consistency risk.
- Use MFS (`ipfs files`) to build/edit directory structures instead of raw object patching.
Example fix
// before ipfs object patch <raw-dagpb-cid> add-link name <target> # fails // after # only if you know the node is not UnixFS: ipfs object patch --allow-non-unixfs <cid> add-link name <target>
Defensive patterns
Strategy: validation
Validate before calling
node, err := api.Dag().Get(ctx, path.New(targetCid))
if err != nil {
return err
}
pb, ok := node.(ipldprime.Node) // inspect Data via dag-pb codec
// confirm the node is a UnixFS directory before AddLink; otherwise use MFS Try / catch
ip, err := api.Object().AddLink(ctx, base, name, child, opts)
if err != nil && strings.Contains(err.Error(), "non-UnixFS dag-pb") {
// rebuild the directory with MFS or retry with --allow-non-unixfs
} Prevention
- Build and edit directories via MFS rather than raw object patching.
- Only AddLink onto nodes produced by `ipfs add` (UnixFS).
- Inspect node type with `ipfs dag get` before patching.
- Reserve SkipUnixFSValidation for deliberately non-UnixFS workflows.
When it happens
Trigger: Calling AddLink on a dag-pb node whose Data field is not valid UnixFS protobuf (raw dag-pb node, custom data, or empty), with SkipUnixFSValidation=false (the default).
Common situations: Manually crafted dag-pb nodes added via the DAG API, then edited with `ipfs object patch <cid> add-link`; HAMT-shard directories with deserialized data; nodes created by other tools with non-UnixFS Data.
Related errors
- cannot remove links from a non-UnixFS dag-pb node; pass --al
- unexpected Objects len
- Import.UnixFSFileMaxLinks must be positive, got %d
- Import.UnixFSDirectoryMaxLinks must be non-negative, got %d
- Import.UnixFSHAMTDirectoryMaxFanout must be a power of 2, be
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/90473690210f8e2b.
Report an issue: GitHub.