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
- Set cardinalityThreshold to a value between 0 and 100 in the related indices config (0 disables the pruning).
- If you wanted to prune very common keywords, use a percentage like 80–90 rather than a document count.
- 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
- Validate related-config values at site-config load time, not at query time
- Treat the threshold as a percentage and clamp/reject out-of-range values in your own config schema
- Add a config test that builds the site with your related settings to catch bad values in CI
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
- invalid index type %q. Must be one of %v
- redirects must have either From or FromRe set
- failed to decode related config: %w
- failed to create config from result: %w
- failed to create config: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/78ece3fafb916381.json.
Report an issue: GitHub ↗.