gohugoio/hugo · warning
duplicate menu entry with identifier
Error message
duplicate menu entry with identifier %q in menu %q
What it means
While assembling site navigation, two menu entries resolved to the same identifier (KeyName) within the same menu. Hugo logs this as a warning (s.Log.Warnln) and keeps only the first entry, so it is non-fatal but produces an incomplete/incorrect menu. The duplicate typically arises when page front matter declares a menu entry whose identifier collides with one from sectionPagesMenu, another page, or the explicit menus config.
Solutions
- Make each menu entry's identifier unique by setting an explicit identifier (or name) in front matter: menu: main: { identifier: "unique-id" }.
- Decide whether the duplicate should come from sectionPagesMenu or from front matter, and remove the other source.
- Rebuild and confirm the warning no longer appears; verify the rendered menu has the intended entries.
Example fix
// before (two pages, both)
+++
menu: { main: { name: "Docs" } }
+++
// after (give unique identifiers)
+++
menu: { main: { identifier: "docs-intro", name: "Docs" } }
+++ Defensive patterns
Strategy: validation
Validate before calling
// Before building, ensure every menu entry identifier is unique per menu.
func validateMenuIDs(entries []MenuEntry) error {
seen := map[string]bool{}
for _, e := range entries {
key := e.Menu + "/" + e.Identifier
if seen[key] {
return fmt.Errorf("duplicate menu entry %q in menu %q", e.Identifier, e.Menu)
}
seen[key] = true
}
return nil
} Prevention
- Set an explicit, unique identifier for every front-matter menu entry.
- Avoid combining sectionPagesMenu with overlapping explicit entries.
- Search your content for duplicate 'menu:' identifiers during content audits.
When it happens
Trigger: Two pages both list menu: main under front matter with the same name/identifier; a page-level menu entry collides with an auto-generated sectionPagesMenu entry (site.go:1484-1490 checks the flat[twoD{name,key}] map before inserting).
Common situations: Setting sectionPagesMenu: main globally while also adding explicit menu entries in page front matter; multiple pages sharing the same title used as the menu identifier; renaming pages without updating menu identifiers.
Related errors
- --appendPort=false not supported when in multihost mode
- cache dir contains unresolved placeholders
- cannot unmarshal CSV into %T: invalid targetType: expected…
- config needs a filename
- config not set
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/f7f8b95d3135c24f.
Report an issue: GitHub.
Appendix: source
Thrown at hugolib/site.go:1487
Name: p.LinkTitle(),
Weight: p.Weight(),
},
Page: p,
}
navigation.SetPageValues(&me, p)
flat[twoD{sectionPagesMenu, me.KeyName()}] = &me
return false, nil
}); err != nil {
return nil, err
}
}
// Add menu entries provided by pages
if err := s.pageMap.forEachPage(pagePredicates.ShouldListGlobal, func(p *pageState) (bool, error) {
for name, me := range p.pageMenus.menus() {
if _, ok := flat[twoD{name, me.KeyName()}]; ok {
err := p.wrapError(fmt.Errorf("duplicate menu entry with identifier %q in menu %q", me.KeyName(), name))
s.Log.Warnln(err)
continue
}
flat[twoD{name, me.KeyName()}] = me
}
return false, nil
}); err != nil {
return nil, err
}
// Create Children Menus First
for _, e := range flat {
if e.Parent != "" {
children[twoD{e.Menu, e.Parent}] = children[twoD{e.Menu, e.Parent}].Add(e)
}
}
// Placing Children in Parents (in flat)View on GitHub (pinned to 52c9bd7908)