gohugoio/hugo · error

unsupported data file extension

Error message

unsupported data file extension %q

What it means

Returned by addPagesFromGoTmplFi when a file routed as TypeContentData (a Go-template data file that generates pages) has an extension that is not a Go-template extension (files.IsGoTmplExt returns false). Hugo's data-driven page generation requires .tmpl/.gotmpl/.html templates; any other extension placed in the content data path is unsupported.

Solutions

  1. If the file is a page-generating template, rename it to use .tmpl or .gotmpl (e.g. mypages.html.tmpl).
  2. If the file is meant as data, move it to /data (Hugo's data source) instead of /content.
  3. Review mediaTypes and module mounts to ensure the extension is classified as intended.
  4. Check the path type logic: only files the path parser tags as TypeContentData reach this branch.

Example fix

# before
/content/books.json   (rejected: unsupported data file extension ".json")
# after
/data/books.json      (data file) OR
/content/books.tmpl   (page-generating template)
Defensive patterns

Strategy: type-guard

Validate before calling

func isGoTmplExt(ext string) bool {
    switch strings.ToLower(strings.TrimPrefix(ext, ".")) {
    case "tmpl", "gotmpl", "html": return true
    }
    return false
}

Type guard

func isContentDataTemplate(fi hugofs.FileMetaInfo) bool {
    return fi.Meta().PathInfo != nil && fi.Meta().PathInfo.Type() == paths.TypeContentData && isGoTmplExt(fi.Meta().PathInfo.Ext())
}

Prevention

When it happens

Trigger: A file under /content with a path type that routes it into the content-data (pages-from-template) pipeline but whose extension is not .tmpl/.gotmpl/.html — e.g. a misplaced .json, .yaml, .csv, or .txt that the path classifier treated as content data. This indicates a path/classification mismatch.

Common situations: Placing a data file (.json/.yaml) directly in /content expecting it to be data when Hugo expects it under /data; a content-nested template misnamed; a custom mediaTypes/paths config reclassifying extensions unexpectedly; upgrading Hugo where content-data routing changed.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/63d68990f349077e. Report an issue: GitHub.

Appendix: source

Thrown at hugolib/content_map.go:333

		}

		m.treePages.InsertWithLock(pm.pathInfo.Base(), pm)
	}
	return
}

func (m *pageMap) addPagesFromGoTmplFi(fi hugofs.FileMetaInfo, buildConfig *BuildCfg) (pageCount uint64, resourceCount uint64, addErr error) {
	meta := fi.Meta()
	pi := meta.PathInfo

	m.s.Log.Trace(logg.StringFunc(
		func() string {
			return fmt.Sprintf("insert pages from data file: %q", fi.Meta().Filename)
		},
	))

	if !files.IsGoTmplExt(pi.Ext()) {
		addErr = fmt.Errorf("unsupported data file extension %q", pi.Ext())
		return
	}

	sitesMatrix := fi.Meta().SitesMatrix

	s := m.s.h.resolveFirstSite(sitesMatrix)
	h := s.h

	contentAdapter := s.pageMap.treePagesFromTemplateAdapters.Get(pi.Base())
	var rebuild bool
	if contentAdapter != nil {
		// Rebuild
		contentAdapter = contentAdapter.CloneForGoTmpl(fi)
		rebuild = true
	} else {
		contentAdapter = pagesfromdata.NewPagesFromTemplate(
			pagesfromdata.PagesFromTemplateOptions{
				GoTmplFi: fi,

View on GitHub (pinned to 52c9bd7908)