ipfs/kubo · error
HAMT fanout must be a power of 2, between 8 and 1024 (got %d
Error message
HAMT fanout must be a power of 2, between 8 and 1024 (got %d)
What it means
When sharding a directory as a HAMT, the fanout is the width of each shard's bitfield. The UnixFS spec constrains it to a power of 2 between 8 and 1024 so the bitfield stays byte-aligned; MaxHAMTFanout rejects any other value up front.
Source
Thrown at core/coreiface/options/unixfs.go:241
}
// MaxDirectoryLinks specifies the maximum number of children for UnixFS basic
// directory nodes.
func (unixfsOpts) MaxDirectoryLinks(n int) UnixfsAddOption {
return func(settings *UnixfsAddSettings) error {
settings.MaxDirectoryLinks = n
settings.MaxDirectoryLinksSet = true
return nil
}
}
// MaxHAMTFanout specifies the maximum width of the HAMT directory shards.
// Per the UnixFS spec, the value must be a power of 2, minimum 8
// (for byte-aligned bitfields), and maximum 1024.
func (unixfsOpts) MaxHAMTFanout(n int) UnixfsAddOption {
return func(settings *UnixfsAddSettings) error {
if n < 8 || n&(n-1) != 0 || n > 1024 {
return fmt.Errorf("HAMT fanout must be a power of 2, between 8 and 1024 (got %d)", n)
}
settings.MaxHAMTFanout = n
settings.MaxHAMTFanoutSet = true
return nil
}
}
// SizeEstimationMode specifies how directory size is estimated for HAMT sharding decisions.
func (unixfsOpts) SizeEstimationMode(mode io.SizeEstimationMode) UnixfsAddOption {
return func(settings *UnixfsAddSettings) error {
settings.SizeEstimationMode = &mode
settings.SizeEstimationModeSet = true
return nil
}
}
// Inline tells the adder to inline small blocks into CIDs
func (unixfsOpts) Inline(enable bool) UnixfsAddOption {View on GitHub (pinned to 329838acdf)
Solutions
- Pick the nearest valid power of two within [8,1024]: 8, 16, 32, 64, 128, 256, 512, or 1024
- If the desired value exceeds 1024 (e.g. js-ipfs 2048), clamp to 1024 — it is the maximum the UnixFS spec allows
- If you did not set fanout intentionally, drop the MaxHAMTFanout option and let the default apply
Example fix
// before opt := options.Unixfs.MaxHAMTFanout(2048) // error: between 8 and 1024 // after opt := options.Unixfs.MaxHAMTFanout(1024)
Defensive patterns
Strategy: validation
Validate before calling
func clampHAMTFanout(n int) int {
if n < 8 {
return 8
}
if n > 1024 {
return 1024
}
// snap up to next power of two
p := 8
for p < n {
p *= 2
}
return p
}
n := clampHAMTFanout(desired)
opt := options.Unixfs.MaxHAMTFanout(n) Type guard
func isPowerOfTwoInRange8to1024(n int) bool {
return n >= 8 && n <= 1024 && n&(n-1) == 0
} Try / catch
opts, err := options.Unixfs.Add(options.Unixfs.MaxHAMTFanout(n))
if err != nil {
if strings.Contains(err.Error(), "HAMT fanout") {
// retry with spec-legal default
opts, err = options.Unixfs.Add(options.Unixfs.MaxHAMTFanout(256))
}
if err != nil {
return err
}
} Prevention
- Restrict fanout values to {8,16,32,64,128,256,512,1024}
- Snap user input to the nearest power of two before calling MaxHAMTFanout
- Values above 1024 (e.g. js-ipfs 2048) must be clamped to 1024 per the UnixFS spec
- If unsure, skip the option and use the library default fanout
When it happens
Trigger: Calling options.Unixfs.MaxHAMTFanout(n) with n < 8 (e.g. 4), n > 1024 (e.g. 2048), or n not a power of two (e.g. 100, 300), then passing the option to UnixfsAddOptions/Add.
Common situations: Reading 'fanout' defaults from other tools (js-ipfs HAMT uses 2048 in some configs, which kubo rejects); computing fanout as bucket count from data size; typos like 1250; users porting configs where a non-power-of-2 was tolerated.
Related errors
- Import.UnixFSHAMTDirectoryMaxFanout must be a power of 2, be
- Import.UnixFSHAMTDirectorySizeEstimation must be %q, %q, or
- unknown CID version: %d
- mtime nanoseconds must be in range [1, 999999999]
- Import.UnixFSFileMaxLinks must be positive, got %d
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/f4b8dde1a0a55552.
Report an issue: GitHub.