ipfs/kubo · error

Import.UnixFSHAMTDirectoryMaxFanout must be a power of 2, be

Error message

Import.UnixFSHAMTDirectoryMaxFanout must be a power of 2, between 8 and 1024 (got %d)

What it means

ValidateImportConfig enforces the HAMT directory parameter constraints from the UnixFS spec: UnixFSHAMTDirectoryMaxFanout must be a power of 2 between 8 and 1024 (8, 16, 32, 64, 128, 256, 512, 1024). HAMT bit width is derived from fanout, so any other value produces an out-of-spec DAG.

Source

Thrown at config/import.go:112

			return fmt.Errorf("Import.UnixFSFileMaxLinks must be positive, got %d", maxLinks)
		}
	}

	// Validate UnixFSDirectoryMaxLinks
	if !cfg.UnixFSDirectoryMaxLinks.IsDefault() {
		maxLinks := cfg.UnixFSDirectoryMaxLinks.WithDefault(DefaultUnixFSDirectoryMaxLinks)
		if maxLinks < 0 {
			return fmt.Errorf("Import.UnixFSDirectoryMaxLinks must be non-negative, got %d", maxLinks)
		}
	}

	// Validate UnixFSHAMTDirectoryMaxFanout if set
	if !cfg.UnixFSHAMTDirectoryMaxFanout.IsDefault() {
		fanout := cfg.UnixFSHAMTDirectoryMaxFanout.WithDefault(DefaultUnixFSHAMTDirectoryMaxFanout)

		// Valid values are powers of 2 between 8 and 1024: 8, 16, 32, 64, 128, 256, 512, 1024
		if fanout < 8 || !isPowerOfTwo(fanout) || fanout > 1024 {
			return fmt.Errorf("Import.UnixFSHAMTDirectoryMaxFanout must be a power of 2, between 8 and 1024 (got %d)", fanout)
		}
	}

	// Validate BatchMaxNodes
	if !cfg.BatchMaxNodes.IsDefault() {
		maxNodes := cfg.BatchMaxNodes.WithDefault(DefaultBatchMaxNodes)
		if maxNodes <= 0 {
			return fmt.Errorf("Import.BatchMaxNodes must be positive, got %d", maxNodes)
		}
	}

	// Validate BatchMaxSize
	if !cfg.BatchMaxSize.IsDefault() {
		maxSize := cfg.BatchMaxSize.WithDefault(DefaultBatchMaxSize)
		if maxSize <= 0 {
			return fmt.Errorf("Import.BatchMaxSize must be positive, got %d", maxSize)
		}
	}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set the fanout to one of the allowed powers of 2: 8, 16, 32, 64, 128, 256, 512, 1024
  2. Remove the key to use DefaultUnixFSHAMTDirectoryMaxFanout (256)
  3. Verify the value with a quick check: n>0 && (n&(n-1))==0, 8<=n<=1024

Example fix

// before
{"Import": {"UnixFSHAMTDirectoryMaxFanout": 100}}
// after
{"Import": {"UnixFSHAMTDirectoryMaxFanout": 128}}
Defensive patterns

Strategy: validation

Validate before calling

func validFanout(n uint32) bool {
	return n >= 8 && n <= 1024 && n&(n-1) == 0
}
// allowed: 8, 16, 32, 64, 128, 256, 512, 1024

Try / catch

if err := config.ValidateImportConfig(&importCfg); err != nil {
	if strings.Contains(err.Error(), "HAMTDirectoryMaxFanout") {
		importCfg.UnixFSHAMTDirectoryMaxFanout = config.DefaultUnixFSHAMTDirectoryMaxFanout
		err = config.ValidateImportConfig(&importCfg)
	}
	return err
}

Prevention

When it happens

Trigger: Setting Import.UnixFSHAMTDirectoryMaxFanout to a value that is not a power of two, or below 8, or above 1024 (e.g. 100, 4, or 2048) and triggering import validation.

Common situations: Tuning HAMT fanout for large directories with an arbitrary number like 100; misreading docs and picking a non-power-of-2; porting settings from another implementation with different bounds.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/e715944482aa88aa. Report an issue: GitHub.