gohugoio/hugo · error

cardinalityThreshold threshold must be between 0 and 100

Error message

cardinalityThreshold threshold must be between 0 and 100

What it means

Hugo's related-content engine (used by .Site.RegularPages.Related and the `related` site config) validates each configured index at config decode time. `cardinalityThreshold` is expressed as a percentage of documents a keyword may appear in before it is treated as too common and dropped from the inverted index, so any value outside 0–100 is rejected and site config loading fails.

Source

Thrown at related/inverted_index.go:595

	if c.ToLower {
		for i := range c.Indices {
			c.Indices[i].ToLower = true
		}
	}
	for i := range c.Indices {
		// Lower case name.
		c.Indices[i].Name = strings.ToLower(c.Indices[i].Name)

		icfg := c.Indices[i]
		if icfg.Type == "" {
			c.Indices[i].Type = TypeBasic
		}
		if !validTypes[c.Indices[i].Type] {
			return c, fmt.Errorf("invalid index type %q. Must be one of %v", c.Indices[i].Type, maps.Keys(validTypes))
		}
		if icfg.CardinalityThreshold < 0 || icfg.CardinalityThreshold > 100 {
			return Config{}, errors.New("cardinalityThreshold threshold must be between 0 and 100")
		}
	}

	return c, nil
}

// StringKeyword is a string search keyword.
type StringKeyword string

func (s StringKeyword) String() string {
	return string(s)
}

// FragmentKeyword represents a document fragment.
type FragmentKeyword string

func (f FragmentKeyword) String() string {
	return string(f)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Set cardinalityThreshold to a value between 0 and 100 in the related indices config (0 disables the pruning).
  2. If you wanted to prune very common keywords, use a percentage like 80–90 rather than a document count.
  3. Remove the key entirely to accept the default of 0.

Example fix

# before (hugo.toml)
[related]
  [[related.indices]]
    name = "tags"
    cardinalityThreshold = 500

# after
[related]
  [[related.indices]]
    name = "tags"
    cardinalityThreshold = 80
Defensive patterns

Strategy: validation

Validate before calling

if cfg.CardinalityThreshold < 0 || cfg.CardinalityThreshold > 100 {
    return fmt.Errorf("cardinalityThreshold must be 0-100, got %d", cfg.CardinalityThreshold)
}

Prevention

When it happens

Trigger: Setting `related.indices[].cardinalityThreshold` in hugo.toml/hugo.yaml to a negative number or a value above 100. The check runs in DecodeConfig in related/inverted_index.go when Hugo loads site configuration, i.e. on any `hugo` or `hugo server` invocation.

Common situations: Developers assume the threshold is an absolute document count (e.g. 500) rather than a percentage; typos like -1 intended to mean 'disabled'; copy-pasting related-content config from blog posts that used fictional values.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/78ece3fafb916381.json. Report an issue: GitHub ↗.